如何在保存之前获取Django ImageField的内容?

时间:2012-01-08 04:39:16

标签: python django file-upload django-models

我正在尝试在保存模型实例的同时调整图像大小。

class Picture(models.Model):
  image_file = models.ImageField(upload_to="pictures")
  thumb_file = models.ImageField(upload_to="pictures", editable=False)
  def save(self, force_insert=False, force_update=False):
    image_object = Image.open(self.image_file.path)
    #[...] nothing yet
    super(Picture, self).save(force_insert, force_update)

问题是在保存模型之前self.image_file.path不存在。它返回一个正确的路径,但图像还没有。由于没有图像,我无法在PIL中打开它以进行调整大小。

我想将缩略图存储在thumb_file(另一个ImageField)中,所以我需要在保存模型之前进行处理。

是否有一种打开文件的好方法(可能在内存中获取tmp图像对象)或者我是否必须首先保存整个模型,调整大小然后再次保存?

3 个答案:

答案 0 :(得分:2)

我使用this snippet

import Image

def fit(file_path, max_width=None, max_height=None, save_as=None):
    # Open file
    img = Image.open(file_path)

    # Store original image width and height
    w, h = img.size

    # Replace width and height by the maximum values
    w = int(max_width or w)
    h = int(max_height or h)

    # Proportinally resize
    img.thumbnail((w, h), Image.ANTIALIAS)

    # Save in (optional) 'save_as' or in the original path
    img.save(save_as or file_path)

    return True

在模特中:

def save(self, *args, **kwargs):
    super(Picture, self).save(*args, **kwargs)
    if self.image:
        fit(self.image_file.path, settings.MAX_WIDTH, settings.MAX_HEIGHT)

答案 1 :(得分:0)

也许您可以直接打开文件并将生成的文件句柄传递给Image.open

image_object = Image.open(self.image_file.open())

抱歉,我现在无法测试。

答案 2 :(得分:0)

在您的模型save方法中,对于FileField,字段值将是有效ImageFileFieldImageField。这个django类实现了目标文件接口(即readwrite),它甚至可以在文件与模型一起保存之前工作,因此您可以将它用作PIL.Image.open的参数:

class Picture(models.Model):
    image_file = models.ImageField(upload_to="pictures")
    thumb_file = models.ImageField(upload_to="pictures", editable=False)

    def save(self, force_insert=False, force_update=False):
        img = Image.open(self.image_file)
        # work with img, is an Image object
        super(Picture, self).save(force_insert, force_update)

这适用于django >= 1.5