我正在通过tutorial了解如何加载图片,我完全失去了这个人用来为提交的图片生成缩略图的方法
这是他的代码的缩减:
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)
所以我对此的具体问题是:
super(Image, self).save(*args, **kwargs)
会保存模型。但他为什么最后再打电话呢?NamedTemporaryFile()
扮演的角色以及调用self.thumbnail.save(thumb_fn, File(open(tf.name)), save=False)
时究竟发生了什么答案 0 :(得分:2)
我也会将ImageField用于主图像。的ImageField 继承自FileField,但确保只有图像文件 上传,除其他外: https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ImageField
首先save()
将图像对象保存到数据库,但它(假设)还没有设置缩略图。第二次save()
调用使用对实例所做的更改(添加缩略图)更新数据库。
他用缩略图字段设置
self.thumbnail.save(thumb_fn, File(open(tf.name)), save=False)
,
但这只会将缩略图保存到适当位置的文件中,并使用其路径填充实例的thumbnail
attr。然后,您需要再次在Image实例上调用save()
以将对象上的更改更新为DB(添加缩略图)。
代码正在读取上传的主图像文件,并且该图像在内存中组成了缩略图(在内存中,它还不作为文件存在)。
但是这个缩略图需要保存在一个文件中,以便它可以与Django ImageFile
一起使用(期望上传的文件暂时保存在磁盘上),这就是他正在做的事情{ {1}}。
NamedTemporaryFile
实例需要将该文件复制到适当的位置(使用ImageFile
设置+ MEDIA_ROOT
参数设置)。