widgets tipos personalizados formularios fields ejemplos crear avanzados django-forms django-crispy-forms formsets

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 %}