0

On my Django Project I have a model that a property is used to store videos in a specific and single Google Cloud Storage bucket, using FileField.

The model is defined like this:

from storages.backends.gcloud import GoogleCloudStorage
from django.conf import settings

DEFAULT_STORAGE = GoogleCloudStorage(bucket_name=settings.DEFAULT_GCS_BUCKET)

class Recording(models.Model):
    raw_file_gcp = models.FileField(blank=True, null=True, storage=DEFAULT_STORAGE)

The problem is that, there's a new architecture that we need to use in which a new storage comes into play... A second bucket, in which a video is transfereed from one bucket to another.

To do that, we dynamically update the .name attribute of the file whenever we need to move a file from one bucket to another, like this:

recording.raw_file_gcp.name = path_with_retention_bucket # Here we update on demand the secondary bucket path.
recording.save(update_fields=["raw_file_gcp", "updated_at"]) 

It's working and all, but, for some reason, every time the above rule is executed, the system keeps asking me to run a migration. And it generates a migration automatically...

This is the migration it generates, whenever the code above is executed:

migrations.AlterField(
    model_name='recording',
    name='raw_file_gcp',
    field=models.FileField(blank=True, null=True, storage=myapp.models.CustomStorage(bucket_name='default-bucket')),
)

But nothing has actually changed in the model...

To try avoiding this unnecessary AlterField migration, I implemented a custom storage class using @deconstructible and __eq__, like this:

from django.utils.deconstruct import deconstructible
from storages.backends.gcloud import GoogleCloudStorage

@deconstructible
class NeutralGCSStorage(GoogleCloudStorage):
    def __eq__(self, other):
        return isinstance(other, NeutralGCSStorage)

And on my storage definition I used this neutral gcs definition:

DEFAULT_STORAGE = NeutralGCSStorage(bucket_name=settings.DEFAULT_GCS_BUCKET)

But Django still generates the same migration. How can I prevent Django from generating migrations when the only difference is the dynamic storage bucket used in a FileField? The one we change it on demand...

6
  • So even if the bucket name remains the same, it generates a migration, or what do you mean with `"dynamic bucket logic"? Commented Jul 21 at 20:08
  • The migration you show uses CustomStorage by the way, not NeutralGCSStorage... Commented Jul 21 at 20:16
  • @willeM_VanOnsem yeah, we're just updating the file name at runtime to switch buckets, but django keeps detecting changes and generating alterfield migrations, even with eq overridden in a custom storage class. nothing in the model actually changed. any idea how to make django ignore this? Commented Jul 21 at 21:11
  • 1
    I think this answer should help you stackoverflow.com/a/79284440/16494437 Commented Jul 22 at 7:30
  • @PTomasz Nice. It's similar to another approach I was suggested to read as well: adamj.eu/tech/2025/05/03/… Commented Jul 22 at 18:52

1 Answer 1

1

In Django FileField you can choose function as source of the storage. In order to do that create new function

def default_google_cloud_storage():
    return GoogleCloudStorage(bucket_name=settings.DEFAULT_GCS_BUCKET)

and use it without calling as storage in your FileField

class Recording(models.Model):
    raw_file_gcp = models.FileField(
                          blank=True, 
                          null=True, 
                          storage=default_google_cloud_storage
                          )
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.