Ajax 手动填充ImageField

Ajax 手动填充ImageField,ajax,django,file-upload,Ajax,Django,File Upload,我有一个models.ImageField,有时会用相应的。有时候,我不想使用表单,而是想用ajax帖子更新图像字段。我正在传递图像文件名和图像内容(base64编码),以便在api视图中获得所需的一切。但我真的不知道如何手动执行此操作,因为我一直依赖于表单处理,表单处理会自动填充models.ImageField 如何手动填充具有文件名和文件内容的models.ImageField 编辑 我已达到以下状态: instance.image.save(file_name, File(StringI

我有一个
models.ImageField
,有时会用相应的。有时候,我不想使用表单,而是想用ajax帖子更新图像字段。我正在传递图像文件名和图像内容(base64编码),以便在api视图中获得所需的一切。但我真的不知道如何手动执行此操作,因为我一直依赖于表单处理,表单处理会自动填充
models.ImageField

如何手动填充具有文件名和文件内容的
models.ImageField

编辑 我已达到以下状态:

instance.image.save(file_name, File(StringIO(data)))
instance.save()
这是使用
ImageField
中的
upload\u to
中配置的正确值更新文件引用

但是它没有保存图像。我原以为第一个
.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()
    
    编辑3
    因此,在进行了更多的尝试之后,我发现我的第一个实现做了正确的事情,但是如果传递的数据格式错误(我错误地传递了base64而不是解码的数据),那么它就会自动失败。我将此作为解决方案发布

    只需保存文件和实例:

    instance.image.save(file_name, File(StringIO(data)))
    instance.save()
    

    不知道此用例的文档在哪里。

    您可以直接使用MemoryUploadedFile中的
    来保存数据:

    file = cStringIO.StringIO(base64.b64decode(request.POST['file']))
    image = InMemoryUploadedFile(file,
       field_name='file',
       name=request.POST['name'],
       content_type="image/jpeg",
       size=sys.getsizeof(file),
       charset=None)
    instance.image = image
    instance.save()
    

    我想您可以将图像保存到一个路径,然后创建如下模型:
    instance=model()
    instance.imagefield=
    然后创建
    instance.save()
    。这行吗?@ShangWang:我想避免手工编写代码。ImageField已经做到了这一点,还有更多(支持不同的存储、基于
    上传到
    的文件分割等)。我希望干净地重用该功能。