【问题标题】:django - FormSet: ingore forms contaning only initial valuesdjango - FormSet:忽略仅包含初始值的表单
【发布时间】:2016-06-08 20:30:07
【问题描述】:

我有一个 FormSet,每个表单都包含一个具有初始值的字段:

class IssueForm(forms.Form):

    date_of_issue = forms.DateField(
            initial=date.today().strftime("%d.%m.%Y"),
            widget=forms.TextInput(attrs={
                'placeholder': date.today().strftime("%d.%m.%Y"),
                'class': 'form-control',
            }),
            localize=True,
            required=True)

现在用户显示了 10 个额外的表单,但他/她可能只填写了其中的 5 个。现在字段 date_of_issue 是必需的,因此在提交 formSet 后它将再次显示并标记用户未填写的那 5 行。

我尝试为该字段添加我自己的 clean 函数,但我不知道这是否可行:

def clean_date_of_issue(self):
    if len(self.cleaned_data) == 1 and 'date_of_issue' in self.cleaned_data:
        self.cleaned_data = dict()
        return None
    return self.cleaned_data['date_of_issue']

【问题讨论】:

  • 你当前的 clean 函数的结果是什么?它有什么问题?
  • @HåkenLid 我再次显示表单,那些只有一个填写字段的表单(带有初始值的 date_of_issue)被标记为“需要填写”(因为表单的其他字段是必需的)。我不知道清洁功能是否可行...
  • 我明白了。我发现一旦你开始对方法和功能进行任何重要的覆盖,你就会失去 django 表单框架的很多便利。在这种情况下,我会考虑要么删除占位符,要么为此找到一些客户端解决方案。一个javascript“今天”按钮来填写日期,也许。或者一个 javascript 函数,在提交时预先验证表单集,并过滤掉仅填写 date_of_issue 的子表单。
  • 我没有使用过多的表单集,所以我不能给你一个如何在服务器端完成的建议。看起来clean_field 方法不起作用,因此需要确定要覆盖的其他方法。我会看看changed_data 属性和django.forms.forms.BaseForm class.has_changed 方法

标签: python django django-forms formset


【解决方案1】:

感谢@håken-lid 将我推入代码中。我一开始就应该这样做。

最后我不知道是什么把戏。我已经覆盖了大部分干净的函数并检查了验证级别的错误(阅读docs。它有帮助!)

有一件事是show_hidden_​​initial。表单似乎有必要识别初始值没有改变:

class IssueForm(forms.Form):
    # ...

    date_of_issue = forms.DateField(
            initial=date.today().strftime("%d.%m.%Y"),
            show_hidden_initial=True,
            widget=forms.TextInput(attrs={
                'placeholder': date.today().strftime("%d.%m.%Y"),
                'class': 'form-control, datepicker',
            }),
            localize=True,
            required=True)

另一种方法是覆盖表单清理函数并删除错误(不是一个很好的解决方案):

class IssueForm(forms.Form):
    # ...

    def clean(self):
        cleaned_data = super(IssueForm, self).clean()

        # get all non default fields
        not_default_fields = [value for key, value in cleaned_data.items() if key not in ('date_of_issue', 'issuer')]

        if any(not_default_fields) is False and 'value' in self.errors:
            # remove the error if it's the only one
            self.errors.pop('value')

        return cleaned_data

我不知道为什么一开始它没有像预期的那样工作,但现在它确实......

【讨论】:

    猜你喜欢
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 2019-03-06
    • 1970-01-01
    • 2010-12-31
    • 2019-02-05
    • 1970-01-01
    相关资源
    最近更新 更多