我们可以从Django中的验证函数内部调整ImageField的大小吗



在Django中从验证函数内部修改数据合法吗?我需要从ImageFields自动重影图像。

在文档中,它说这类函数应该引发ValidationError,但我需要实际修改数据(在本例中为image)。我想这样做,因为我必须把它应用到几个模型上。如果我能做到这一点,我就不需要在管理员中更改表单了。

def image_field_autoresize(image):
    if image.width > MAX_IMAGE_WIDTH:
        raise ValidationError(u'image width error')
    if image.height > MAX_IMAGE_HEIGHT:
        raise ValidationError(u'image height error')

经过与@karthikr的讨论,我可以得出以下结论:

如果需要在验证过程中更改数据,可以覆盖ModelForm类中的clean_<fieldname>()。在ModelForm中的clean()方法中,您不应该这样做。如果你需要调整图像大小,我发现最好的地方是Model的save()方法。

我已经解决了这样的问题:

我创建了一个名为image.py的新模块,其中包含一个函数,该函数以图像的绝对路径为参数,实现调整大小逻辑并修改图像大小。在我的例子中,如果宽度大于给定的大小,"调整大小逻辑"会按比例缩小图像。

from PIL import Image
from django.conf import settings

def autoresize_image(image_path):
    image = Image.open(image_path)
    width = image.size[0]
    if width > settings.IMAGE_MAX_WIDTH:
        height = image.size[1]
        reduce_factor = settings.IMAGE_MAX_WIDTH / float(width)
        reduced_width = int(width * reduce_factor)
        reduced_height = int(height * reduce_factor)
        image = image.resize((reduced_width, reduced_height), Image.ANTIALIAS)
        image.save(image_path)

我从包含要调整大小的ImageField的Model中的save()方法调用此函数。这里需要记住的是:在尝试调整图像大小之前调用super(),否则将找不到它,因为它还没有保存在hdd中,如果不需要ImageField,请检查是否给定了值。它看起来像:

def save(self, *args, **kwargs):
    super(Startup, self).save(*args, **kwargs)
    if self.logo:
        autoresize_image(self.logo.path)

感谢@Jingo的评论。它非常有用:)

最新更新