ImageField在保存时调整大小也会更新width_field和height_field

时间:2012-03-07 20:40:26

标签: django model imagefield

我有一个包含ImageField的模型,上传后应调整大小。

class SomeModel(models.Model):
    banner = ImageField(upload_to='uploaded_images',
                        width_field='banner_width',
                        height_field='banner_height')
    banner_width = models.PositiveIntegerField(_('banner width'), editable=False)
    banner_height = models.PositiveIntegerField(_('banner height'), editable=False)

def save(self, *args, **kwargs):
    super(SomeModel, self).save(*args, **kwargs)
    resize_image(filename=self.banner.path,
                 width=MAX_BANNER_WIDTH,
                 height=MAX_BANNER_HEIGHT)

resize_image是一个自定义函数,用于调整大小,一切正常,但在调整大小之前,banner_width和banner_height会填充原始图像的尺寸。

已调整大小的图像的实际大小可能小于给定的MAX值,因此我必须打开调整大小的文件以在调整大小后检查其实际尺寸。然后我可以手动设置banner_widthbanner_height,然后重新保存,但这不是有效的方法。 我还可以先调整大小,设置宽度和高度字段,然后保存,但在执行保存之前,位置self.banner.path上的文件不存在。

有关如何正确完成的任何建议?

1 个答案:

答案 0 :(得分:3)

经过几个小时的尝试,我已经改变了解决这个问题的方法,并定义了CustomImageField这样:

class CustomImageField(ImageField):
    attr_class = CustomImageFieldFile

    def __init__(self, resize=False, to_width=None, to_height=None, force=True, *args, **kwargs):
        self.resize = resize
        if resize:
            self.to_width = to_width
            self.to_height = to_height
            self.force = force
        super(CustomImageField, self).__init__(*args, **kwargs)


class CustomImageFieldFile(ImageFieldFile): 

    def save(self, name, content, save=True):
        super(CustomImageFieldFile, self).save(name, content, save=save)
        if self.field.resize:
            resized_img = resize_image(filename=self.path,
                                       width=self.field.to_width,
                                       height=self.field.to_height,
                                       force=self.field.force)
            if resized_img:
                setattr(self.instance, self.field.width_field, resized_img.size[0])
                setattr(self.instance, self.field.height_field, resized_img.size[1])

现在我可以定义:

class SomeModel(models.Model):
    my_image = CustomImageField(resize=True, to_width=SOME_WIDTH, to_height=SOME_HEIGHT, force=False,
                                width_field='image_width', height_field='image_height')
    image_width = models.PositiveIntegerField(editable=False)
    image_height = models.PositiveIntegerField(editable=False)

根据resize参数,上传后图像可以自动调整大小,并且正确更新宽度/高度字段,而不保存对象两次。经过快速测试后,似乎工作正常。