django forms - tipos - Errores no formales para un formulario que no se procesa con las formas crujientes de Django
post django (2)
¡Gracias a @Brandon por ayudarme a resolver esto!
En la vista, formset.__dict__
se puede usar para imprimir el objeto en sí mismo para descubrir dónde se almacenan los errores. Hacer eso mostró que los errores de formset se almacenan usando la clave _non_form_errors
. Luego pasé esos errores a la plantilla!
Implemente un método de limpieza personalizado para validar mi formset. Sé que hay un error, ya que puedo imprimirlos en la consola, pero estos non_form_errors () nunca se representan en mi plantilla. ¿Cómo puedo renderizarlos?
template.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"
),
)
Después de muchas investigaciones, encontré la solución para renderizar non_form_errors
de BaseInlineFormSet
crujiente en plantilla mediante el filtro nativo de django-crispy
. Tal vez sería útil para alguien (funciona al menos para django-crispy-forms
== 1.5.2, Django
== 1.6):
{% load crispy_forms_filters %}
{% if formset.non_form_errors %}
{{ formset|as_crispy_errors }}
{% endif %}