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()
great post, helpful. thx.
ReplyDeleteI see, this isn't a very clean approach, suppose the "if-part" of save() method takes some long time, during this time unscaled image and old thumbnail (or no at all) would be served to users.
ReplyDeleteIs this first super.save() really necessary? Can we call save() one time after "if"?