Normalize name and size images in Django (and adding thumbnails)

You can connect with me on LinkedIn to discuss collaborations and work opportunities.

You can also follow me on Twitter, Bluesky and Mastodon.

I wanted to assign an image to every element in a model. I wanted them to have a thumbnail, and to have normalized sizes and names. And of course, I want my application to do everything automatically.

The best method I've found is next, modifying models.py (note that PIL must be installed):

def rename_image(src, field, id):
    file_ext = os.path.splitext(src)[1].lower().replace('jpg', 'jpeg')
    dst = 'img/uploaded/work_%s/%s_%s%s' % (field, field, id, file_ext)
    return dst



def resize_image(src, dst, size):
    from PIL import Image
    image = Image.open(src)
    image.thumbnail(size, Image.ANTIALIAS)
    image.save('%s%s' % (settings.MEDIA_ROOT, dst))
    return dst



class MyModel(models.Model):
    image = models.ImageField(upload_to='img/uploaded/work_image', verbose_name=_('imagen'))
    thumbnail = models.ImageField(editable=False, upload_to='img/uploaded/work_thumbnail')
    [...]



    def save(self):
        super(MyModel, self).save()
        if self.image != rename_image(self.image, 'image', self.id):
            original_filename = self.get_image_filename()
            self.thumbnail = resize_image(original_filename, rename_image(original_filename, 'thumbnail', self.id), [100, 75])
            self.image = resize_image(original_filename, rename_image(original_filename, 'image', self.id), [640, 480])
            if os.path.exists(original_filename):
                os.remove(original_filename)
            super(MyModel, self).save()

You can connect with me on LinkedIn to discuss collaborations and work opportunities.

You can also follow me on Twitter, Bluesky and Mastodon.