Save Media Files to Local Disk on Django-Storages

I’m using django-storages for storing my media files such us images, or document files to amazon S3. But if we using django-storages, by default all media files will uploaded to remote storage, in my case I’m using amazon S3.

I’m writing simple script to save both on remote and also local disk. To use this class, you just need to subclass this mixin class. Keep in mind to pay attention with mixin class order.

import os
from django.conf import settings
from django.core.files import File
from django.core.files.storage import FileSystemStorage
class LocalMediaSaveMixin(object):
"""Mixin class to for backing up media files on model that has
image/file fields. To use it, ensure to keep in my python multiple
inheritance order. The top most hierarchy must be on the most right.
example:
class MyModel(LocalMediaSaveMixin, models.Model):
pass
"""
def __init__(self, *args, **kwargs):
super(LocalMediaSaveMixin, self).__init__(*args, **kwargs)
# Setup django local file system storage.
self.storage = FileSystemStorage()
self.storage.base_location = settings.MEDIA_ROOT
self.media_fields = [
i for i in self._meta.fields
if i.__class__.__name__ in ['ImageField', 'FileField']
]
def save(self, *args, **kwargs):
"""Save media file (Image, File) to local storage."""
from product.models import file_path # This import was from function that use to define path location and used on `upload_to=`
super(LocalMediaSaveMixin, self).save(*args, **kwargs)
# Getting file or image fields.
for field in self.media_fields:
raw_file = getattr(self, field.name)
file_name = os.path.split(raw_file.name)[1]
django_file = File(raw_file, file_name)
root, _ = os.path.split(file_path(None, file_name))
root = root.replace('static/', '')
# Ensure the file is not exists.
if not os.path.isfile(os.path.join(settings.MEDIA_ROOT, root, file_name)):
self.storage.location = os.path.join(settings.MEDIA_ROOT, root)
self.storage.save(file_name, django_file)
@property
def local_media(self):
"""Listed all local media directory."""
media = {}
for i in self.media_fields:
raw_file = getattr(self, i.name)
media[i.name] = os.path.join(settings.MEDIA_ROOT, raw_file.name.replace('static/', ''))
return media
view raw mixins.py hosted with ❤ by GitHub

Currently only support save to local disk, but not supported yet to remove local file if the instance removed. Don’t hesitate to fork or improve my code. 😀

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.