Image model with thumbnail

A relatively simple Photo model which generates its own thumbnail when saved. A default size is specified as thumb_size in the save() arguments.

Other thumbnailing strategies don't save the thumbnail dimensions, and since the actual dimensions of the thumbnail created by PIL's thumbnail method are somewhat non-deterministic, it is difficult to create an img tag with proper height and width attributes. This approach makes that task simple.

This approach works well if only one thumbnail size is required. It could easily be adapted to support two or three thumbnail sizes, but adding more sizes would quickly get unwieldy.

fromPILimportImagefromcStringIOimportStringIOfromdjango.core.files.uploadedfileimportSimpleUploadedFileclassPhoto(models.Model):title=models.CharField(max_length=100)image=models.ImageField(upload_to="photos/originals/%Y/%m/")image_height=models.IntegerField()image_width=models.IntegerField()thumbnail=models.ImageField(upload_to="photos/thumbs/%Y/%m/")thumbnail_height=models.IntegerField()thumbnail_width=models.IntegerField()caption=models.CharField(max_length=250,blank=True)def__str__(self):return"%s"%self.titledef__unicode__(self):returnself.titledefsave(self,force_update=False,force_insert=False,thumb_size=(180,300)):image=Image.open(self.image)ifimage.modenotin('L','RGB'):image=image.convert('RGB')# save the original sizeself.image_width,self.image_height=image.sizeimage.thumbnail(thumb_size,Image.ANTIALIAS)# save the thumbnail to memorytemp_handle=StringIO()image.save(temp_handle,'png')temp_handle.seek(0)# rewind the file# save to the thumbnail fieldsuf=SimpleUploadedFile(os.path.split(self.image.name)[-1],temp_handle.read(),content_type='image/png')self.thumbnail.save(suf.name+'.png',suf,save=False)self.thumbnail_width,self.thumbnail_height=image.size# save the image objectsuper(Photo,self).save(force_update,force_insert)