Django的ClearableFileInput小部件不会在提交时传递初始(“当前”)值

时间:2012-09-18 15:10:55

标签: django django-forms

我的基本目标是创建一个表单(使用ModelForm)预先填充来自现有数据库对象的数据,允许用户修改这些数据,然后将提交的表单另存为 new 对象。 (排序为“复制”,然后“粘贴修改”设置。)除了文件字段和ClearableFileInput小部件之外,这种方式正常。

thisthisthis等问题的答案清楚地表明,文件字段不能也不应该使用初始值填充。

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

  

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

(有点令人困惑,但我认为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小部件显示:

Currently with clearing checkbox, Change... input http://phagesdb.org/static/formDisplay.png

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

所以:

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

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

1 个答案:

答案 0 :(得分: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