【问题标题】:django ModelFormSet returns with errors, want to display all forms except the empty onesdjango ModelFormSet 返回错误,想要显示除空表单之外的所有表单
【发布时间】:2013-02-01 11:57:26
【问题描述】:

使用 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 只显示一个空白表单(字段集)。用户可以按一个按钮来显示其余的表格。如果表单返回验证错误,我可以使用 jquery 查找具有类 errorlist 的字段集并显示所有这些字段集。但是,我还想显示任何包含有效数据的字段集。我可以检查每个字段集中的所有元素以查看它们是否具有值,但这似乎很笨拙。 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() 添加前缀会导致返回表单的初始数据丢失?

【问题讨论】:

  • 您是否在覆盖结束时返回 self.cleaned_data?
  • 不,您不需要 ModelFormSet。默认实现只是检查新对象不违反模型的唯一约束。

标签: django django-forms formset


【解决方案1】:

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

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

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

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

【讨论】:

  • 我没有意识到我可以从模板中调用表单的方法。如果这可行,无论如何这将是更清洁的解决方案。我会在星期一试试。
  • 假设你的意思是 form.has_changed,这行得通。谢谢艾丹!
猜你喜欢
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
  • 2018-07-23
  • 1970-01-01
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多