Django - 手动将图像保存到 ImageField 字段

Posted

技术标签:

【中文标题】Django - 手动将图像保存到 ImageField 字段【英文标题】:Django - Saving an image manually to an ImageField field 【发布时间】:2011-12-15 05:53:03 【问题描述】:

以下代码在保存后获取图像并从中制作缩略图:

class Image(models.Model):
    image     = models.ImageField(upload_to='images')
    thumbnail = models.ImageField(upload_to='images/thumbnails', editable=False)

    def save(self, *args, **kwargs):
       super(Image, self).save(*args, **kwargs)
       if self.image:
           from PIL import Image as ImageObj
           from cStringIO import StringIO
           from django.core.files.uploadedfile import SimpleUploadedFile

           try:
               # thumbnail
               THUMBNAIL_SIZE = (160, 160)  # dimensions

               image = ImageObj.open(self.image)

               # Convert to RGB if necessary
               if image.mode not in ('L', 'RGB'): image = image.convert('RGB')

               # create a thumbnail + use antialiasing for a smoother thumbnail
               image.thumbnail(THUMBNAIL_SIZE, ImageObj.ANTIALIAS)

               # fetch image into memory
               temp_handle = StringIO()
               image.save(temp_handle, 'png')
               temp_handle.seek(0)

               # save it
               file_name, file_ext = os.path.splitext(self.image.name.rpartition('/')[-1])
               suf = SimpleUploadedFile(file_name + file_ext, temp_handle.read(), content_type='image/png')

               self.thumbnail.save(file_name + '.png', suf, save=False)
           except ImportError:
               pass

一切正常,原图+缩略图都在上传,图片路径也正确。

唯一的问题是缩略图没有被分配新创建的缩略图的路径 - 它在数据库中是空的。我已经阅读了文档,看起来如果我使用 save=True 保存缩略图应该可以解决我的问题:

self.thumbnail.save(file_name + '.png', suf, save=True)

但是,这样做会引发以下问题:

Django Version: 1.3.1
Exception Type: IOError
Exception Value:    
cannot identify image file

我不知道我做错了什么。

【问题讨论】:

【参考方案1】:

尝试传递实际文件内容而不是 SimpleUploadedFile 对象:

self.thumbnail.save(file_name + '.png', temp_handle.read(), save=True)

https://docs.djangoproject.com/en/dev/ref/files/file/#additional-methods-on-files-attached-to-objects how to manually assign imagefield in Django Programmatically saving image to Django ImageField

【讨论】:

我已经尝试过了,它给出了以下错误:异常类型:AttributeError 异常值:'str'对象没有属性'chunks'【参考方案2】:

我只是通过移动解决了我的问题:

super(Image, self).save(*args, **kwargs)

到 def save() 的末尾。我仍然不确定为什么会这样,但我唯一的解释是 save() 本身正在将字段值保存到数据库中,因此它需要在最后执行。

【讨论】:

以上是关于Django - 手动将图像保存到 ImageField 字段的主要内容,如果未能解决你的问题,请参考以下文章

将解码的临时图像保存到 Django Imagefield

无法将图像上传到 Django 项目,获取表单对象没有属性“保存”

如何将图像上传到 Django

数据未保存在 Django 中的数据库中

如何保存具有多个图像的 django 模型?

Django ImageField 保存到位置