【问题标题】:Non Form Errors for a Formset not Rendering with Django Crispy Forms未使用 Django Crispy Forms 呈现的表单集的非表单错误
【发布时间】:2015-06-06 16:15:20
【问题描述】:

我实现了一个自定义清理方法来验证我的表单集。我知道有错误,因为我可以将它们打印到控制台,但这些 non_form_errors() 永远不会在我的模板中呈现。我该如何渲染它们?

模板.html:

<form action="{% url 'databank:register' %}" method="post" enctype="multipart/form-data">
  {% csrf_token %}

  <div class="container">
    <div class="row" style="margin-top: 30px"> 
      <div class="col-md-10 col-md-offset-1">
        {{ dataset_form.media }}
        {% crispy dataset_form %}
          <div class="authorFormset">
            {% for form in formset %}
              {% crispy form helper %}
            {% endfor %}    
          </div>
        {% crispy terms_form %}
      </div>
    </div>
  </div>

  <div class="container">
    <div class="row">
      <div class="col-md-10 col-md-offset-1">
        <input type="submit" class="btn btn-lg btn-success" value="Submit">
      </div>
    </div>
</div>
{{ formset.management_form }}

forms.py:

class BaseAuthorFormset(BaseFormSet):
    def clean(self):   
        if any(self.errors):
            return
        roles = []
        for form in self.forms:
            contributor_role = form.cleaned_data['role']
            for x in contributor_role:
                if (x == "Depositor") and (x in roles):
                    raise forms.ValidationError("Only one Contributor may be marked Depositor.")
                roles.append(x)
            if "Depositor" not in roles:
                raise forms.ValidationError("You must designate one Contributor as Depositor.")

    def __init__(self, *args, **kwargs):
        super(BaseAuthorFormset, self).__init__(*args, **kwargs)
        for form in self.forms:
            form.empty_permitted = False

class AuthorForm(forms.Form):

    first_name = forms.CharField(
        max_length=96,
        required=True,
    )

    middle_initial = forms.CharField(
        max_length=96,
        required=False,
    )

    last_name = forms.CharField(
    max_length = 96,
    required = True,
    )

    email = forms.EmailField(
        required = True
    )

    role = forms.ModelMultipleChoiceField(
        queryset=AuthorRole.objects.filter(is_visible=True),
        widget=forms.CheckboxSelectMultiple,
        required = False,
    )

    affiliation = forms.CharField(
        max_length=512,
        required=True,
    )


AuthorFormset = formset_factory(AuthorForm, formset=BaseAuthorFormset, extra=1)

class AuthorFormHelper(FormHelper):

    def __init__(self, *args, **kwargs):
        super(AuthorFormHelper, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        FormHelper.form_tag = False
        FormHelper.disable_csrf = True
        FormHelper.formset_error_title = "Contributor Errors"
        self.layout = Layout(
            Div(
                Div( HTML("<h4>Contributor</h4>"),
                    Div(
                        Div('first_name', css_class='col-xs-4'),
                        Div('middle_initial', css_class='col-xs-4'),
                        Div('last_name', css_class='col-xs-4'),
                        css_class='row'
                    ),
                    Div(
                        Div('affiliation', css_class='col-xs-12 col-sm-6'),
                        Div('email', css_class='col-xs-12 col-sm-6'),
                        Div(
                            Field(
                                InlineCheckboxes('role'),
                            ), 
                            css_class='col-xs-12 col-sm-6'),
                        css_class='row'
                    ),
                ),
                css_class = 'add_author',
                id="authorFormDiv"
            ),
        )

【问题讨论】:

  • 如果是“默认”错误,则会按预期显示错误,例如某个字段中的错误,但我在自定义清理方法中定义的错误不会在任何地方输出
  • 我尝试在 clean 方法的正下方添加cleaned_data = super(BaseAuthorFormset, self).clean(),但仍然不起作用......有什么想法吗??我真的被困住了!

标签: django-forms django-crispy-forms formsets


【解决方案1】:

经过大量调查,我找到了通过原生django-crispy的过滤器在模板中渲染non_form_errors的解决方案。也许它会对某人有所帮助(它至少适用于django-crispy-forms==1.5.2、Django==1.6):

{% load crispy_forms_filters %}
{% if formset.non_form_errors %}
    {{ formset|as_crispy_errors }}
{% endif %}

【讨论】:

    【解决方案2】:

    感谢@Brandon 帮助我解决这个问题!

    在视图中,formset.__dict__ 可用于打印出对象本身以找出错误存储在何处。这样做表明表单集错误是使用_non_form_errors 键存储的。然后我将这些错误传递给模板!

    【讨论】:

      猜你喜欢
      • 2015-05-13
      • 2013-10-06
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      相关资源
      最近更新 更多