0

One view I have is using a modelform with custom field cleaning. One type of cleaning is checking if the user is trying to submit a change to a field that is already set to the value, and it works exactly how I want it to work by throwing a ValidationError. The problem of course is that I can only submit one form at a time, so I'd like to use a modelformset to submit multiple forms.

I know it is possible to override the modelformset's clean method, but I'm asking if it's possible to use the modelform's field cleaning methods on the modelformset?. Currently when I submit the modelformset with empty fields the is_valid() passes which seems strange to me...

I also would like to know "typically" where the custom modelformset validation code would go? I was thinking with the forms.py.

*Edit -- with answer. My httpResponseRedirect was allowing the form to be submitted without validation.

def mass_check_in(request):
    # queryset
    qs = Part.objects.none()
    errlst=[]
    c = {}
    c.update(csrf(request))

    # Creating a model_formset out of PartForm
    PartFormSetFactory = modelformset_factory(model=Part,
                                              form=PartForm,
                                              formset=BasePartFormSet, 
                                              extra=2)
    if request.method == 'POST':
        PartFormSet = PartFormSetFactory(request.POST)
        if PartFormSet.is_valid():
            PartFormSet.save()
            return http.HttpResponseRedirect('/current_count/')

    else:        
        PartFormSet = PartFormSetFactory(queryset=qs, initial=[
                                                               {'serial_number':'placeholder',
                                                                },
                                                               {'serial_number':'placeholder'
                                                                }])

    return render(request,'mass_check_in.html',{
                                           'title':'Add Item',
                                           'formset': PartFormSet,
                                           'formset_errors': PartFormSet.non_form_errors(),
                                           })
Zach Mance
  • 95
  • 9

1 Answers1

4

If you don't enter any data at all in one of the modelforms in your model formset, it will skip validation for that form; from the docs:

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

You can actually disable this functionality though by forcing empty_permitted=False on the forms; see the accepted answer to this question for more: Django formsets: make first required?

Formsets do have their own clean method, but it's used to validate information between two or more forms in the formset, not for validating the individual forms themselves (which should be taken care of in the forms clean method - as you are doing now.

A formset has a clean method similar to the one on a Form class. This is where you define your own validation that works at the formset level:

Here's another similar question:

Django formset doesn't validate

Community
  • 1
  • 1
Timmy O'Mahony
  • 53,000
  • 18
  • 155
  • 177
  • Thank you for your clear explanation! But for some reason my modelformset isn't validating at the form level and/or at the formset level. my code is here ---> http://dpaste.com/787964/. Thank you Timmy. – Zach Mance Aug 17 '12 at 18:48