3

我的基本目标是创建一个表单(使用ModelForm)预填充现有数据库对象中的数据,允许用户修改这些数据,然后将提交的表单保存为对象。(类似于“复制”然后“粘贴修改”设置。)除了文件字段和 ClearableFileInput 小部件外,这工作正常。

像thisthisthis这样的问题的答案清楚地表明文件字段不能也不应该填充初始值。

然而,在ClearableFileInput小部件上的 Django 文档说:

文件上传输入:<input type='file' ...>如果该字段不是必需的且具有初始数据,则带有一个额外的复选框输入以清除该字段的值。

(已经有点混乱了,但我假设 Django 指的是具有初始值的模型<input type='file' ...>字段,而该字段仍然是空白的?)

因此,如果我使用任何一种方法:

>>> obj = Foo.objects.get(pk=1)
>>> obj.fooFile.name
u'files/foo1.txt'
>>> f = FooForm(instance=obj)

或这种方法:

f = FooForm(initial={'fooFile':Foo.objects.get(pk=1).fooFile})

为了实例化我的表单,ClearableFileInput 小部件显示:

目前清除复选框,更改...输入 http://phagesdb.org/static/formDisplay.png

但是,当用户在不更改此字段的情况下提交表单时,“当前”行中的值似乎完全丢失给 Django。它似乎不在request.POSTform.cleaned_data中。当我调用.is_valid()然后.save()在绑定的 ModelForm 上时,新对象中的文件字段最终为空白。

所以:

  1. ClearableFileInput 小部件是否传递“当前”值?如果不是,那么 ClearableFileInput 小部件是否具有误导性和/或用途非常有限?我假设返回的值将是“当前...”中的值,除非我使用“更改...”输入。

  2. 如何捕获该值,以便在我调用时出现在我的新对象中.save()?(请记住,我不能使用f = FooForm(request.POST, request.FILES, instance=obj),因为我想要一个新对象,而不是修改后的对象。)

4

1 回答 1

0

在您的表单中放置一个隐藏字段,并使用您作为初始传入的图像的路径预填充它。然后编写一个类似于以下的保存方法。

这将向用户显示,好像文件字段已预先填充,将文件保存到新实例,并允许他们使用清除复选框,或上传他们自己的图像。

from django.core.files.base import ContentFile
def save(self, commit=True):
    insance = super(FormClass, self).save(False)
    if not instance.file_field and self.cleaned_data['file_field_path'] and not self.data.get('file_field-clear'):
        path = os.path.join(settings.MEDIA_ROOT, self.cleaned_data['file_field_path'])
        with open(path) as f:
            file_object = ContentFile(f.read())
            instance.file_field.save(self.cleaned_data['file_field_path'], file_object, False)

    if commit:
        insance.save()
    return insance
于 2012-12-04T22:07:59.357 回答