Henry George
Henry George

Reputation: 514

Adding form validation to django modelform by overriding clean

I have a long modelform with mostly modelform validation, and I'd like to have a 'Please correct the errors below' error at the top of my form, when any of the individual fields fail to validate. I attempted to do this by overriding the clean method on the modelform, but there are no errors at this point.

# models.py
class MyModel(models.Model):
    myfield = models.IntegerField(default=0, validators=[MinValueValidator(0)])

# forms.py
class MyModelForm(forms.ModelForm)
    class Meta:
        models = MyModel
        fields = ['myfield']

    def clean(self):
        cleaned_data = super().clean()
        if any([field.errors for field in self]):
            raise forms.ValidationError("Please correct the errors below.")
        return cleaned_data

When I enter an invalid value, such as -1, the field still shows the correct error message beneath it, but the form does not have any errors.

I'm using {% crispy %} to render the form, which automatically places the form errors at the top, so it's not a template issue.

The issue (from the debugger) is that at the point when clean() is being called, form['myfield'].errors is empty.

Upvotes: 0

Views: 1885

Answers (2)

Alasdair
Alasdair

Reputation: 308939

As Daniel says, you would normally check form.errors in the template instead of raising another error in the clean method.

If you really want to do this in the clean method, then check self.errors instead of individual field errors.

def clean(self):
    cleaned_data = super().clean()
    if self.errors:
        raise forms.ValidationError("Please correct the errors below.")
    return cleaned_data

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599628

That's not something you would do in the form. You would do it in the template:

{% if form.errors %}
    Please correct the errors below.
    ... now list the errors ...
{% endif %}

In fact, that is almost exactly what the admin change form template does.

Upvotes: 2

Related Questions