I have the S3 storage backend set up and I am able to upload files to the S3 bucket. I am using the boto and django-storages modules. The config in settings.py looks like this:
AWS_STORAGE_BUCKET_NAME = 'xxxxx'
AWS_ACCESS_KEY_ID = 'xxxxxxxxxxxxx'
AWS_SECRET_ACCESS_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
STATICFILES_LOCATION = 'static'
STATICFILES_STORAGE = 'custom_storages.StaticStorage'
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)
MEDIAFILES_LOCATION = 'media'
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'
and the class in models.py:
class Model (models.Model):
name = models.CharField(max_length=50, null=False, blank=False)
file = models.FileField(upload_to='models/%Y/%m/%d/')
What I need is modify the file with an external program, which was possible with the default storage backend (using local disk) followingly:
def modify_model(model):
try:
subprocess.check_call(["/usr/bin/program", model.file.path])
except:
pass
As the S3 backend does not support the path attribute, I am wondering how should I do it correctly? The error looks like this:
>>> m.file.path
Traceback (most recent call last):
File "<console>", line 1, in <module>
File ".../site-packages/django/db/models/fields/files.py", line 64, in _get_path
return self.storage.path(self.name)
File ".../site-packages/django/core/files/storage.py", line 111, in path
raise NotImplementedError("This backend doesn't support absolute paths.")
NotImplementedError: This backend doesn't support absolute paths.
My first thoughts are saving the file locally, modifying it and then uploading the modified version.
>>> f = open('localfile', 'wb')
>>> m = Model.objects.first()
>>> f.write(m.file.read())
1503
>>> f.close()
>>> # modify the file here
>>> f = open('localfile', 'rb')
>>> m.file.save(os.path.basename(m.file.name), File(f))
This works as intended, BUT - Is there a way to work with the Django FieldFile class natively (with the S3 backend) to modify the files without creating the temporary ones?