Reputation: 17
Should my django-storage instance be storing the S3 signature in the database along with the image name?
If so how do you regenerate a new key on each request assuming the old request expiration is already past?
models.py
def user_directory_path(self, filename):
return 'profile/user_{0}/images/profile/{1}'.format(self.user.id, filename)
...
...
user_image = models.ImageField(upload_to=user_directory_path, storage=PrivateMediaStorage(), blank=True)
storage_backends.py
class PrivateMediaStorage(S3Boto3Storage):
location = 'private'
default_acl = 'private'
file_overwrite = False
custom_domain = False
Sorry new to Django, want to make sure my logic is correct.
Upvotes: 0
Views: 1031
Reputation: 12859
No you don't want it to be storing that kind of data because then you'll lose access to the file. I've had this exact problem in the past.
The signature should be added by the system at the time the file needs to be accessed.
These are my settings, which work without saving the signature, for a private S3 storage bucket;
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
S3_BUCKET = env('S3_BUCKET', 'my_bucket')
S3_SUB_BUCKET = env('S3_SUB_BUCKET', 'dev')
S3_REGION = env('S3_REGION', 'eu-west-2')
AWS_REGION = env('AWS_REGION', 'eu-west-2')
S3_USE_SIGV4 = True
AWS_S3_PATH_SEPARATOR = '/'
AWS_STORAGE_BUCKET_NAME = S3_BUCKET
AWS_S3_HOST = f'{S3_BUCKET}.s3.{S3_REGION}.amazonaws.com'
AWS_S3_SIGNATURE_VERSION = 's3v4'
AWS_S3_ADDRESSING_STYLE = 'virtual'
AWS_DEFAULT_ACL = 'private'
AWS_LOCATION = S3_SUB_BUCKET
AWS_S3_FILE_OVERWRITE = False
Some of the settings you define in your custom storage class I have in the settings which saves sub-classing.
When using a file/image field I then just do;
photo = models.ImageField(
verbose_name=_('photo'),
upload_to='photos',
default=None,
blank=True,
null=True,
)
And on fields where my upload_to
is a callable I have these methods;
def uuid():
""" Generate a UUID """
return urlsafe_b64encode(uuid4().bytes).decode("ascii").rstrip("=")
def upload_path(instance, filename):
""" Upload to path with UUID """
return "{uuid}/{file}".format(uuid=uuid(), file=filename)
The docs for things like AWS_S3_ADDRESSING_STYLE
aren't great, but that's one I missed for a while & it lead to things being stored in unexpected locations within my buckets. I think I was seeing <bucket>/<bucket>/<path_to_file
type issues without that setting.
Upvotes: 1