Search code examples
djangodjango-templatesdjango-formsinline-formset

How do I detect if a formset has any errors at all in a template?


Thanks to the fantastic inline model formsets in django I have a pretty advanced form with 4 inline formsets. In the template I display each formset in a tab. Everything works really slick but I would like to color a tab red if the formset in that tab has any validation errors at all. So I tried this:

<div id="tabs">
    <ul>
        <li><a href="#foo-tab"{% if forms.FooFormSet.errors %} class="error"{% endif %}>Foo</a></li>
        <li><a href="#bar-tab"{% if forms.BarFormSet.errors %} class="error"{% endif %}>Bar</a></li>
        <li><a href="#zoo-tab"{% if forms.ZooFormSet.errors %} class="error"{% endif %}>Zoo</a></li>
        <li><a href="#doo-tab"{% if forms.DooFormSet.errors %} class="error"{% endif %}>Doo</a></li>
    </ul>

    <div id="foo-tab"></div>
    <div id="bar-tab"></div>
    <div id="zoo-tab"></div>
    <div id="doo-tab"></div>
</div>

But it doesnt work because forms.*Set.errors is a list with empty dictionarys (so it will always return True) like [{}, {}, {}] (the amount of forms in the formsets is the same amount of empty dictionarys in formset.errors

One solution I think could be to subclass BaseInlineFormSet and add a has_errors method or something, and then use that subclassed base for all my formsets. Any other suggestions? Thanks!


Solution

  • You can check the result of the formset's method is_valid, which in turn checks each form for validity: {% if forms.FooFormSet.is_valid %}.

    As far as I know, it is more or less a no-op (database is not touched, forms are not revalidated) if the forms have already undergone validation, so it is not going to hurt the performance at all.