Reputation: 1696
I have made a formset like this.
class MixedObsCollsForm(forms.Form):
def __init__(self, *args, **kwargs):
project_id = kwargs.pop('project_id')
super(MixedObsCollsForm, self).__init__(*args, **kwargs)
project = get_object_or_404(Project, pk=project_id)
self.fields['photos_upload'] = forms.ImageField(label="Photos", required=False)
taxon = forms.CharField(max_length=80, required=False)
growth_form = forms.ChoiceField(choices = growthFormChoice, required=False)
height = forms.DecimalField(max_value=99, min_value=0, decimal_places=2, required=True)
density = forms.IntegerField(max_value=100, min_value=1, required=False)
And I have a weird way to display it in a view using a class to handle all the processing. But its like this...
class ObservationFormView(object):
def __init__(self, request=None, project_id=None, observation_id=None):
self.request = request
self.ObservationFormSet = formset_factory(form=MixedObsCollsForm, extra=5)
self.ObservationFormSet.form = staticmethod(curry(MixedObsCollsForm, project_id=project_id))
self.project = get_object_or_404(Project, pk=project_id)
self.user = request.user
self.use_type = 'create'
self.formset = self.ObservationFormSet(self.request.POST or None)
def isValid(self):
return self.formset.is_valid() & self.locationForm.is_valid()
def render(self):
return render(self.request, 'observation_form.html', {'use_type': self.use_type, 'formset': self.formset, 'locationForm':self.locationForm, 'project_photos': self.project.photos.all(),})
def processForm(self):
for form in self.formset:
if form.is_valid() == True:
if form.cleaned_data['is_collection'] == True:
collection = self.getOrMakeCollection(form.cleaned_data, self.locationForm.cleaned_data['location'], False)
if form.cleaned_data['is_collection'] == False:
collection = self.getOrMakeCollection(form.cleaned_data, self.locationForm.cleaned_data['location'], True)
observation = self.saveObservation(form.cleaned_data, self.locationForm.cleaned_data['location'], collection)
return observation
The problem is when I render this form in a view even the forms within the formset which are empty don't validate. Reporting "This field is required." next to all the height fields. Even the empty ones.
It was my understanding that the empty forms should always pass validation. I have looked at the management form data and it all looks fine.
If I change required to False it means I end up with IntegrityErrors when I try to save the formset to the database.
Upvotes: 1
Views: 1898
Reputation: 1696
I finally worked out what it was so here it is for anyone else who has this problem, its easy to overlook.
It wasn't even included in the code in the question so there wasn't much help anyone could offer.
This line:
growth_form = forms.ChoiceField(choices = growthFormChoice, required=False)
Used the growthFormChoice
variable which was a tuple of choices like this.
growthFormChoice = (('0', 'Select one'),
('T', 'tree'),
('S', 'shrub'))
Because of this the default value ('0':'Select One')
resulted in passing a 0
to every form which wasn't (intentionally) altered and triggering validation for the rest of the fields. Simply changing it to ('':'Select One')
was all it needed.
Upvotes: 1