Use add_error() for Better Form Validation UX

When validating multiple fields in your form's clean() method, use add_error() instead of raising ValidationError. This shows all validation errors at once instead of making users fix errors one at a time.

Let's say we have a password reset form:

from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _

class PasswordResetForm(forms.Form):
    password = forms.CharField(
        widget=forms.PasswordInput,
        label=_("New Password")
    )
    confirm_password = forms.CharField(
        widget=forms.PasswordInput,
        label=_("Confirm Password")
    )

Using raise (shows only first error): If passwords don't match, user won't see the "Password too short." error until they fix the first one and resubmit.

def clean(self):
    cleaned_data = super().clean()
    password = cleaned_data.get("password")
    confirm_password = cleaned_data.get("confirm_password")

    if password != confirm_password:
        raise ValidationError(_("Passwords don't match."))

    if len(password) < 8:
        raise ValidationError(_("Password too short."))

    return cleaned_data

Using add_error() (shows all errors at once): User sees both errors immediately and can fix everything in one go.

def clean(self):
    cleaned_data = super().clean()
    password = cleaned_data.get("password")
    confirm_password = cleaned_data.get("confirm_password")

    if password != confirm_password:
        self.add_error("confirm_password", _("Passwords don't match."))

    if password and len(password) < 8:
        self.add_error("password", _("Password too short."))

    return cleaned_data

Tips and Tricks Programming User Experience Development Django 6.x Django 5.2 Django 4.2