[Answered ]-Django reupload images when changed upload_to

2👍

So, I think ‘re-uploading’ is the wrong way to think about it — re-uploading the images will still leave the old ones lying around, which (depending on how many images you have) could be a massive waste of space. One way to do this instead would be by the following two step process:

1) Move the files manually, on your server, to the new upload_to location via whatever method is OS appropriate. This could probably all be done with one mv command on linux, if that’s what you’re hosting on.

2) If you just changed the upload_to attribute, and didn’t change the MEDIA_ROOT settings or anything else, what you need to change is the Imagefield’s name property. An ImageField’s name properly usually is a joining of your upload_to string and your image’s filename (this then gets appended to MEDIA_URL to form the images url or MEDIA_ROOT to form the actual upload path). So you could update the models in your Django shell by typing something like this:

import os
from my_app import MyModel

newpath = 'your/new/upload_to/'

for obj in MyModel.objects.all():
    image_name = os.path.split(obj.my_img_field.name)[1]
    obj.my_img_field.name = newpath + image_name
    obj.save()

You can check to see if everything worked properly by calling obj.my_img_field.url and seeing if that points where it should.

0👍

Here’s a little snippet that I made when I needed to do this on many models and didn’t want to do this on th OS level.
For use with strftime this have to be modified though.

models = (YourModel1, YourModel2)

for Model in models:
    for field in Model._meta.get_fields():
        if not hasattr(field, 'upload_to'): 
            continue
        for instance in Model.objects.all():
            f = getattr(instance, field.name)
            if not f:
                continue
            if field.upload_to not in str(f):
                filename = os.path.basename(f.name)
                new_path = os.path.join(field.upload_to, filename)
                os.makedirs(
                    os.path.join(
                        settings.MEDIA_ROOT, 
                        field.upload_to
                    ), 
                    exist_ok=True
                )
                try:
                    shutil.move(
                        os.path.join(settings.MEDIA_ROOT, f.name),
                        os.path.join(settings.MEDIA_ROOT, new_path)
                    )
                    setattr(instance, field.name, new_path)
                except FileNotFoundError as e:
                    logger.error("Not found {}".format(field.name))
                    logger.error(str(e))
                else:
                    instance.save()
👤qocu

Leave a comment