[Fixed]-Django formsets confusion (validation, required, empty_permitted)

24πŸ‘

βœ…

The formset is smart enough to ignore extra forms that were not changed.

Talking about code trying to be too smart. What is this supposed to mean exactly? Why would I even want that?

It seems to mean β€” as you worked out β€” that "extra" forms created by the formset (with extra=N in your example) have empty_permitted set to True. Have a glance at django/forms/formsets.py to see this happening.

formset[0].empty_permitted means that if formset[0].has_changed() == False, no further processing/validation is done. Again, you can see this in action in forms/forms.py.

To prevent this, a blog post suggests defining a custom formset to use in modelformset_factory (or inlineformset_factory) which sets empty_permitted = False:

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

I haven’t tested this, but it looks legit.

As to why anyone might want this, it makes using
django-dynamic-formset much simpler β€” you can send data for form-0 and form-2 and, assuming form-1 was an extra form (i.e. not linked to model data), Django won’t complain. If empty_permitted were False by default, you’d have to worry about skipping the blank form in your own code, or reindexing things in Javascript.

πŸ‘€supervacuo

Leave a comment