In my Django application application I have a formset that is created from a simple (not-model) form, with the extra=1 (to allow javasript to add more forms later on).
class SomeForm(forms.Form):
#some fields with required=False
length = forms.IntegerField(required=False)
# An example of one of the fields with choices i have
A = 0
B = 1
C = 2
D = 3
choices = ((A, 'Aah'), (B, 'Baa'), (C, 'Caa'), (D, 'Daa'))
# This is a required choice field
pickme = forms.ChoiceField(choices=choices)
SomeFormset = formset_factory(SomeForm, can_delete=True, extra=1)
Now, when I create and try to validate it in my view on the POST request:
my_formset = SomeFormset(request.POST, request.FILES)
if(my_formset.is_valid()):
# FAIL
it always fails the above check, if the extra rendered form is submitted empty.
If I check for form.changed_data
on the last empty extra form, I get the fields that have choices on them (like the pickme above).
In other words, the formset is not smart enough to figure out that the empty submitted form should be ignored, when some choice fields are required.
This is not the usual behavior of formsets. Formsets pass empty_permitted=True to all "extra" forms, and a form with empty_permitted that hasn't been modified should always pass validation. Note that this works just fine in the Django admin (if you use inlines).
You must be doing something else in your code that is breaking this behavior somewhere. Post the full code of the relevant form?
Thanks Carl, you led me to discover the root of my problem.
When creating a form with a choice field, which is required, we must set an initial value, otherwise the form will consider that field changed.
So for a form like this:
we do this:
Then when a formset checks the extra form it will see that pickme had an initial value of A, and it is A now as well, and will consider it unchanged.