How to edit Django FieldFile with S3 storage backend

Viewed 1133

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?

0 Answers
Related