I'm using Django 1.4 formsets and I'd like to perform different validation for the first form in the formset.
I have a LocationForm where I display 4 text fields allowing the user to enter up to 4 locations:
class LocationForm(forms.Form):
user_entered_address = forms.CharField(required=False, max_length=255)
full_address = forms.CharField(max_length=255, required=False, widget=forms.HiddenInput())
city = forms.CharField(max_length=255, required=False, widget=forms.HiddenInput())
state = forms.CharField(max_length=255, required=False, widget=forms.HiddenInput())
country = forms.CharField(max_length=255, required=False, widget=forms.HiddenInput())
latitude = forms.CharField(required=False, widget=forms.HiddenInput())
longitude = forms.CharField(required=False, widget=forms.HiddenInput())
LocationFormSet = formset_factory(LocationForm, extra=4, max_num=4)
This works great to display the input fields, but I would like the first LocationForm in the formset to be required and the rest of the forms to be optional (meaning the user must enter at least 1 location in the first form, but the rest are optional).
If I modify the form, removing required=False
:
user_entered_address = forms.CharField(max_length=255)
Then user_entered_address
is required for all forms. I have a feeling I need to write a custom clean() method, but I'm stuck how to find the first form, figure out if user_entered_address
is blank and if so, raise a ValidationError:
class BaseLocationFormSet(BaseFormSet):
def clean(self):
# How to do I find the first form and ensure user_entered_address isn't blank?
LocationFormSet = formset_factory(LocationForm, extra=4, max_num=4, formset=BaseLocationFormSet)
Or is this the wrong approach and there is a better way to do this? Thanks!
You can access the forms like:
form = self.forms[0]
So in your clean just check the first form and ignore the others.
form = self.forms[0]
title = form.cleaned_data['title']
if title is None:
raise forms.ValidationError("Missing title")