django ModelFormSet返回错误,想要显示除空表之外的所有表单

时间:2013-02-16 17:04:29

标签: django django-forms formset

使用django 1.4,我有一个ModelFormSet没有初始实例,额外和最大设置为6:

# forms.py
ChildFormSet = modelformset_factory(Child, formset=FirstRequiredModelFormSet, exclude=('family_application', 'exported', 'index',), extra=6, max_num=6)
child_queryset = Child.objects.none()

当用户第一次访问该页面时,我使用jquery只显示一个空白表单(fieldset)。用户可以按一个按钮来显示其余表格。如果表单返回验证错误,我可以使用jquery查找具有类错误列表的字段集并显示所有这些字段集。但是,我还想显示包含有效数据的任何字段集。我可以检查每个字段集中的所有元素,看看它们是否有值,但这看起来很笨拙。 Django知道表单何时发生了变化,所以我想我会为这些表单添加一个前缀,以便我可以在html中找到它们:

class FirstRequiredModelFormSet(BaseModelFormSet):
    def __init__(self, *args, **kwargs):
        super(FirstRequiredModelFormSet, self).__init__(*args, **kwargs)
        self.forms[0].empty_permitted = False

    def clean(self):
        super(FirstRequiredModelFormSet, self).clean()
        for form in self.forms:
            if form.has_changed():
                form.prefix = '-'.join(('modified', form.prefix))

问题在于,当表单返回错误(没有初始数据时返回)时,我覆盖clean()的方式会以某种方式导致提交的数据丢失。如果我通过首先检查验证错误来提前返回:

def clean(self):
    if any(self.errors):
        return
    super(FirstRequiredModelFormSet, self).clean()
    for form in self.forms:
        if form.has_changed():
            form.prefix = '-'.join(('modified', form.prefix))

,数据仍然存在,但当然不会添加前缀。我想过使用is_bound而不是has_changed(),但似乎所有的表单都从一开始就绑定了,我猜是因为它们是ModelForms。

为什么重写BaseModelFormSet.clean()以添加前缀会导致返回的表单的初始数据丢失?

1 个答案:

答案 0 :(得分:0)

当浏览器将表单发布回服务器时,Django使用前缀来标识哪个表单属于哪个Child对象。我认为你通过添加自己的前缀来搞乱那个系统。

我建议使用不同的系统来识别修改后的表格。我认为您应该能够在模板中使用has_changed()方法,因此您可以执行类似的操作 -

<form class="{% if form.has_changed %}changed{% endif %}">

(注意在模板中调用方法时缺少括号。)