repeating migration when using storage

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.

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