使用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()以添加前缀会导致返回的表单的初始数据丢失?
答案 0 :(得分:0)
当浏览器将表单发布回服务器时,Django使用前缀来标识哪个表单属于哪个Child对象。我认为你通过添加自己的前缀来搞乱那个系统。
我建议使用不同的系统来识别修改后的表格。我认为您应该能够在模板中使用has_changed()
方法,因此您可以执行类似的操作 -
<form class="{% if form.has_changed %}changed{% endif %}">
(注意在模板中调用方法时缺少括号。)