Django - Cannot create migrations for ImageField with dynamic upload_to value Django - Cannot create migrations for ImageField with dynamic upload_to value python python

Django - Cannot create migrations for ImageField with dynamic upload_to value


I am not sure if it is OK to answer my own question, but i just figured out (i think).

According to this bug report, i edited my code:

from django.utils.deconstruct import deconstructible@deconstructibleclass PathAndRename(object):    def __init__(self, sub_path):        self.path = sub_path    def __call__(self, instance, filename):        ext = filename.split('.')[-1]        # set filename as random string        filename = '{}.{}'.format(uuid4().hex, ext)        # return the whole path to the file        return os.path.join(self.path, filename)path_and_rename = PathAndRename("/avatars")

And then, in field definition:

avatar = models.ImageField(upload_to=path_and_rename,                               null=True, blank=True,                               default="avatars/none/default.png",                               height_field="image_height",                               width_field="image_width")

This worked for me.


I had the same problem but I have many ImageFile in my models

head = ImageField(upload_to=upload_to("head")icon = ImageField(upload_to=upload_to("icon")...etc

I don't want create upload_to wraper func for every ImageField column I have.

So I just create a func named wrapper, and it woks

def wrapper():    return

I think it works just fine because I opened migration file and I found this:

('head', models.ImageField(upload_to=wrapper)),

I guess it's not effect migration process


You can create function with kwargs like this:

def upload_image_location(instance, filename, thumbnail=False):    name, ext = os.path.splitext(filename)    path = f'news/{instance.slug}{f"_thumbnail" if thumbnail else ""}{ext}'    n = 1    while os.path.exists(path):        path = f'news/{instance.slug}-{n}{ext}'        n += 1    return path

and use this method with functools.partial in your model:

image = models.ImageField(    upload_to=upload_image_location,    width_field='image_width',    height_field='image_height')thumbnail_image = models.ImageField(upload_to=partial(upload_image_location, thumbnail=True), blank=True)

You will get migration like this:

class Migration(migrations.Migration):    dependencies = [        ('news', '0001_initial'),    ]    operations = [        migrations.AddField(            model_name='news',            name='thumbnail_image',            field=models.ImageField(blank=True, upload_to=functools.partial(news.models.upload_image_location, *(), **{'thumbnail': True})),        ),        migrations.AlterField(            model_name='news',            name='image',            field=models.ImageField(height_field='image_height', upload_to=news.models.upload_image_location, width_field='image_width'),        ),    ]