在Django模型中手动触发图像保存方法

时间:2016-07-16 16:32:32

标签: django image model save field

我有一个带有自定义图像字段的Django模型。图像字段在上传时创建一些缩略图大小。代码可能如下所示:

from django.db import models
from utils import CustomImageField

class Photo(models.Model):
    image = CustomImageField()

现在我修改原始图片,让我说我旋转它。现在我想再次触发我的图像字段的保存方法,以覆盖缩略图并创建旋转版本。因此,我不需要在代码(DRY)中的其他位置旋转缩略图。

有什么想法?这些方面的东西 - 但究竟是怎么回事?

p = Photo.objects.get(pk=1)
p.image.save(...)

我可以完全控制CustomImageField小部件。 save()方法定义为:

def save(self, name, path, save=True):

问题是,我对方法参数使用了什么?

2 个答案:

答案 0 :(得分:3)

此问题看起来像是Programmatically saving image to Django ImageField

的副本

ImageField.save()方法的参数记录在FileField.save()中(其中ImageField是子类): https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.fields.files.FieldFile.save

  

需要两个必需的参数: name ,这是文件的名称,和   内容,这是一个包含文件内容的对象。该   可选的 save 参数控制模型实例是否为   在与此字段关联的文件被更改后保存。   默认为 True

以下是为我们工作的内容:

class CustomImage(models.Model):
    image = models.ImageField(upload_to=get_file_path, max_length=500)
    orig_name = models.TextField()

这是从http资源向ImageField添加图像文件的方法:

from django.core.files.base import ContentFile

def download_photo(amazon_id, url):
    img_data = requests.get(url)
    img = CustomImage(orig_name=img_data.url)
    img.image.save(slugify(img.orig_name), ContentFile(img_data.content), save=True)

没有ContentFile也可以使用:

new_img = File(open(different_obj.image.path), 'r')
img.image.save(different_obj.image.url, new_img, save=True)

另见: - https://docs.djangoproject.com/en/1.9/topics/files/ - https://djangosnippets.org/snippets/2587/

答案 1 :(得分:2)

选项是脏字段检查,可以手动(请参阅此SO question)或使用pypi package

或者,如果您想节省内存,可以从字段的属性设置器触发调整大小(假设您继承自FileField

class CustomImageField(FileField):

    def _set_file(self, file):
        has_file_changed = file != self._file
        super(CustomImageField, self)._set_file(file)
        if has_file_changed:
             self.handle_resizing_etc()

    # need to redeclare property so it points to the right _set_file
    file = property(FileField._get_file, _set_file, FileField._del_file)

免责声明:我没有在生产代码中使用此方法,在发布此答案之前我没有编写概念证明,因此可能无法按预期工作