2

我正在学习如何上传图片的教程,我完全不知道这个人用来为提交的图片生成缩略图的方法

这是他的代码的删减部分:

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)

所以我对此的具体问题是:

  1. 他使用 FileField 作为图像,使用 ImageField 作为缩略图的任何原因?
  2. 据我了解,super(Image, self).save(*args, **kwargs)保存模型。但他为什么最后又叫它?
  3. 然后我不太了解角色扮演以及被调用NamedTemporaryFile()时究竟会发生什么self.thumbnail.save(thumb_fn, File(open(tf.name)), save=False)
4

1 回答 1

2
  1. 我也会将 ImageField 用于主图像。ImageField 继承自 FileField 但确保只能上传图像文件,除其他外: https ://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ImageField

  2. 首先save()将图像对象保存到数据库,但它(据说)还没有设置缩略图。第二次save()调用使用对实例所做的更改更新数据库(添加了缩略图)。

    他用 设置缩略图字段 self.thumbnail.save(thumb_fn, File(open(tf.name)), save=False),但这只会将缩略图保存到适当位置的文件中,并用thumbnail它的路径填充实例的 attr。然后,您需要再次调用save()Image 实例以将对象上的更改更新到 DB(添加了缩略图)。

  3. 代码正在读取上传的主图像文件,并使用内存中的图像组成缩略图(在内存中,它还没有作为文件存在)。

    但是该缩略图需要保存在一个文件中,以便它可以与 Django 一起使用ImageFile(期望上传的文件临时保存在磁盘上),这就是他正在做的NamedTemporaryFile.

    然后,该ImageFile实例负责将该文件复制到适当的位置(使用您的MEDIA_ROOT设置 +upload_to参数设置)。

于 2012-05-27T09:56:53.210 回答