Search code examples
djangodjango-formsdjango-crispy-formsdjango-validation

django modelform validation at the form level


I can have custom validators for my django models and what I would like to do is perform validation at the form level where the form elements have dependencies with each other. To illustrate, say I have the following model:

class MyModel(models.Model):
    num_average = models.IntegerField(verbose_name='Number of averages',
                                      default=1)

    num_values = models.IntegerField(verbose_name='Number of values', 
                                     default=3)

The dependency is that num_values = num_average * 3. I know I can set this automatically but for this purposes let us assume we want the user input. I have a form as:

class MyForm(ModelForm):
    class Meta:
        model = MyModel
        fields = ['num_average', 'num_values']

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)

Is there a way to validate the form as a whole before the submit gets triggered?


Solution

  • Yes, as the form docs point out, this kind of thing is done in a clean method.

    class MyForm(ModelForm):
        class Meta:
            model = MyModel
            fields = ['num_average', 'num_values']
    
        def clean(self):
            data = self.cleaned_data
            if data['num_values'] != data['num_average'] *3:
                raise forms.ValidationError('values must be three times average')
    

    As an aside, you shouldn't define __init__ if you're not doing anything with it; overriding a method just to call the superclass method is pointless.