1

我有一个模型,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_widthand banner_height,然后再次保存,但这不是有效的方法。我也可以先调整大小,设置宽度和高度字段,然后保存,但是在self.banner.path执行保存之前该位置的文件不存在。

关于如何正确完成此操作的任何建议?

4

1 回答 1

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参数,可以在上传后自动调整图像大小,正确更新宽度/高度字段,而无需两次保存对象。经过快速测试,它似乎工作正常。

于 2012-03-27T21:26:32.853 回答