Reputation: 21
Formset is_valid returns "True though the field is empty when Form Class has only one field.
I'd made this example using "python manage.py shell".
As you see, when the "ArticleForm" class has only title field, the formset's is_valid function return "True".
I saw somebody use the has_changed function because of this issue.
But I don't think that's good method to solve this problem.
from django import forms
from django.forms.formsets import formset_factory
class ArticleForm(forms.Form):
title = forms.CharField()
ArticleFormSet = formset_factory(ArticleForm)
data = {
'form-TOTAL_FORMS': '2',
'form-INITIAL_FORMS': '0',
'form-MAX_NUM_FORMS': '',
'form-0-title': 'Test',
'form-1-title': '',
}
formset = ArticleFormSet(data)
formset.is_valid()
#True - I think it has to be "False" because the "form-1-title' is empty
formset.errors
#[{}, {}]
class ArticleForm(forms.Form):
title = forms.CharField()
pub_date = forms.DateField()
ArticleFormSet = formset_factory(ArticleForm)
data = {
'form-TOTAL_FORMS': '2',
'form-INITIAL_FORMS': '0',
'form-MAX_NUM_FORMS': '',
'form-0-title': 'Test',
'form-0-pub_date': '1904-06-16',
'form-1-title': '',
'form-1-pub_date': '1904-06-16',
}
formset = ArticleFormSet(data)
formset.is_valid()
#False - It's working. I think the reason is the pub_date field.
formset.errors
#[{}, {'title': [u'This field is required.']}]
Upvotes: 2
Views: 2344
Reputation: 679
This is the default Django behaviour on empty forms. If Django notices that you have a completely empty form, it ignores it when running validation. In your second example your form is not empty because DateField has a value set.
You could see the advantage of this behaviour if you took a look at Django inlines. Imagine you have set
extra = 3
in your InlineAdmin. User fills in 2 inline forms and leaves out the third. The two forms are then validated properly and the empty one is ignored as one could expect.
In order to validate a one field form you could check your cleaned_data:
if formset.is_valid():
is_really_valid = True
for form in formset.forms:
if not form.cleaned_data.has_key('title'):
is_really_valid = False
break
if this is a one field form, it does not really hurt much to check one field.
Upvotes: 5