I’m working my way through a tutorial on how to up load images, and I’m at a complete loss on the method this guy uses to generate a thumbnail for submitted pictures
Here’s a trimmed down chunk of his code:
import os.path
from PIL import Image as PImage
from settings import MEDIA_ROOT
from tempfile import *
class Image(models.Model):
image = models.FileField(upload_to="images/")
thumbnail = models.ImageField(upload_to="images/", blank=True, null=True)
def save(self, *args, **kwargs):
super(Image, self).save(*args, **kwargs)
im = PImage.open(pjoin(MEDIA_ROOT, self.image.name))
fn, ext = os.path.splitext(self.image.name)
im.thumbnail((128,128), PImage.ANTIALIAS)
thumb_fn = fn + "-thumb" + ext
tf = NamedTemporaryFile()
im.save(tf.name, "JPEG")
self.thumbnail.save(thumb_fn, File(open(tf.name)), save=False)
tf.close()
super(Image, self).save(*args, ** kwargs)
so my specific questions about this are:
- Any reason he uses FileField for the image and ImageField for the thumbnail?
- From what I understand,
super(Image, self).save(*args, **kwargs)saves the model. but why does he call it again at the end? - Then I don’t really understand the role
NamedTemporaryFile()plays and what exactly happens whenself.thumbnail.save(thumb_fn, File(open(tf.name)), save=False)is called
I would use ImageField for the main image as well. ImageField
inherits from FileField but ensures that only image files can be
uploaded, among other things:
https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ImageField
First
save()saves the image object to DB, but it has (supposedly) no thumbnail set yet. Secondsave()call updates the DB with the changes made to the instance (thumbnail added).He sets the thumbnail field with
self.thumbnail.save(thumb_fn, File(open(tf.name)), save=False),but that only saves the thumbnail to a file in the appropriate location and fills in the instance’s
thumbnailattr with the path to it. You then need to callsave()on the Image instance again to update the changes on the object to DB (thumbnail added).The code is reading the uploaded main image file and with that image in memory composes the thumbnail from it (in memory, it does not exist as a file yet).
But that thumbnail needs to be saved on a file so it can be used with Django
ImageFile(that expects an uploaded file temporarily saved on disk) and that is what he is doing withNamedTemporaryFile.The
ImageFileinstance takes then care of copying that file to the appropriate location (set with yourMEDIA_ROOTsetting + theupload_toargument).