【发布时间】:2016-02-25 11:34:32
【问题描述】:
我有一个models.ImageField,有时我会用相应的forms.ImageField 填充它。有时,我不想使用表单,而是想使用 ajax POST 更新图像字段。我同时传递了图像文件名和图像内容(base64 编码),因此在我的 api 视图中我拥有我需要的一切。但我真的不知道如何手动执行此操作,因为我一直依赖表单处理,它会自动填充models.ImageField。
如何手动填充具有文件名和文件内容的models.ImageField?
编辑
我已达到以下状态:
instance.image.save(file_name, File(StringIO(data)))
instance.save()
这是更新文件引用,使用在upload_to 中配置的正确值ImageField。
但是它没有保存图像。我会想象第一个.save 电话会:
- 在配置的存储中生成文件名
- 将文件内容保存到所选文件,包括处理为此
ImageField(本地 FS、Amazon S3 或其他)配置的任何类型的存储 - 更新对
ImageField中文件的引用
第二个.save 实际上会将更新后的实例保存到数据库中。
我做错了什么?如何确保新图像内容以自动生成的文件名实际写入磁盘?
编辑2
我有一个非常不令人满意的解决方法,它有效但非常有限。这说明了直接使用ImageField 可以解决的问题:
# TODO: workaround because I do not yet know how to correctly populate the ImageField
# This is very limited because:
# - only uses local filesystem (no AWS S3, ...)
# - does not provide the advance splitting provided by upload_to
local_file = os.path.join(settings.MEDIA_ROOT, file_name)
with open(local_file, 'wb') as f:
f.write(data)
instance.image = file_name
instance.save()
EDIT3
所以,在玩了一些之后,我发现我的第一个实现是在做正确的事情,但是如果传递的数据格式错误(我错误地传递了 base64 而不是解码的数据),就会默默地失败。我会将此作为解决方案发布
【问题讨论】:
-
我认为您可以将图像保存到路径,然后创建模型,例如:
instance = Model()instance.imagefield = <image_path>然后instance.save()。这行得通吗? -
@ShangWang:我想避免手动编写这段代码。 ImageField 已经做到了这一点,还有更多(支持不同的存储、基于
upload_to的文件拆分等)。我想干净利落地重用这个功能。
标签: ajax django file-upload