Hi all,
I’ve an annoynig problem that thus far I could not solve even with ChatGPT. It concerns the following.
Ive a model:
class Image(UUIDModel):
# image are stored via storage Managing files | Django documentation | Django
image_data = models.ImageField(upload_to=upload_image_path, storage=storages[settings.DS_IMAGES_STORAGE_NAME])
With these settings:
DS_IMAGES_STORAGE_NAME = “s3_ds_images”
STORAGES = {
“default”: {
“BACKEND”: “django.core.files.storage.FileSystemStorage”,
},
DS_IMAGES_STORAGE_NAME: {
“BACKEND”: “storages.backends.s3.S3Storage”,
“OPTIONS”: {
“bucket_name”: os.environ.get(“DJANGO_AWS_STORAGE_BUCKET_NAME”, “ai-tool-ds-images”),
“region_name”: os.environ.get(“DJANGO_AWS_S3_REGION_NAME”),
},
},
“staticfiles”: {
“BACKEND”: “django.contrib.staticfiles.storage.StaticFilesStorage”,
},
}
Every makemigrations generates a migration file claiming:
Alter field image_data on image
But the field never changes. ChatGPT gave some options like using functions but nothing worked.
Why is this and what does work?
Context:
Django 5.0.4
django-debug-toolbar 4.3.0
django-extensions 3.2.3
django-filter 24.2
django-storages 1.14.2
djangorestframework 3.15.2
python 3.10.12
I’m pretty sure you are running into this issue .
Thanks for the reply. It is appreciated.
I tried:
from django.db.migrations.writer import SettingsReference
upload_root_reference = SettingsReference(settings.DS_IMAGES_STORAGE_NAME, ‘DS_IMAGES_STORAGE_NAME’)
class Image(UUIDModel):
# image are stored via storage Managing files | Django documentation | Django
image_data = models.ImageField(upload_to=upload_image_path, storage=storages[upload_root_reference])
But without effect.
anefta
July 30, 2024, 8:36am
4
Sometimes, explicitly setting the storage backend in the model field can help. Here’s how you might do it:
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
class Image(UUIDModel):
image_data = models.ImageField(
upload_to=upload_image_path,
storage=S3Boto3Storage(
bucket_name=settings.STORAGES[settings.DS_IMAGES_STORAGE_NAME]['OPTIONS']['bucket_name'],
region_name=settings.STORAGES[settings.DS_IMAGES_STORAGE_NAME]['OPTIONS']['region_name']
)
)
Example of Updated Settings:
DS_IMAGES_STORAGE_NAME = "s3_ds_images"
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
DS_IMAGES_STORAGE_NAME: {
"BACKEND": "storages.backends.s3boto3.S3Boto3Storage",
"OPTIONS": {
"bucket_name": os.environ.get("DJANGO_AWS_STORAGE_BUCKET_NAME", "ai-tool-ds-images"),
"region_name": os.environ.get("DJANGO_AWS_S3_REGION_NAME"),
},
},
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
},
}
FYI
Again thanks for the support, but sadly it does not work.
I started experimenting a little bit and it turned out is wasn’t the storages after all but upload_to . I used a class to generate key (as a singleton) like this:
class ImageToKeyConvertor:
def image_to_key(image, filename):
return f"{image.upload.id}/{image.id}/{filename}"
image_to_key_convertor = ImageToKeyConvertor()
upload_image_path = image_to_key_convertor.image_to_key
That did not work, however making the method static did the trick:
class ImageToKeyConvertor:
@staticmethod
return f"{image.upload.id}/{image.id}/{filename}"
1 Like