Here is a simple solution I implemented for my video uploads that could be uploaded using different storage.
- Implement a storage class that acts as a wrapper to the actual storage implementation:
@deconstructible(path="travel.apps.vod.models.VideoStorage")
class VideoStorage:
def __init__(self):
self.storage = storages[settings.VOD_STORAGE]
def __getattr__(self, item):
return getattr(self.storage, item)
If you want you can inherit from Storage class, and implement all of its methods, by calling the method self.storage, but I prefer this short implementation.
- Use an instance of this storage on your file field:
class SomeClass(models.Model):
file = models.File(storage=ViedeoStorage(), ....)
Note: Since the class in my implementation is not a subclass of Storage you need to use an instance as in storage=ViedeoStorage(), instead of a callable, otherwise Django will raise an error.
- Define different storage classes in your settings (it's up to you how to handle this part)
STORAGES = {
'default': {
'BACKEND': self.DEFAULT_STORAGE_CLASS,
},
'staticfiles': {
'BACKEND': 'travel.core.storage.CompressedManifestStaticFilesStorage',
},
'local': {
'BACKEND': 'django.core.files.storage.FileSystemStorage',
},
's3': {
'BACKEND': 'storages.backends.s3.S3Storage',
},
}
VOD_STORAGE = 's3'
Now whenever you change the VOD_STORAGE to select a different storage for your files, no migration will be generated.
P.S. you'll have one migration after you changed to this new storage, but this it.