Max_length messages from error_messages do not override default message of existing MaxLengthValidators

RegisterForm is based on the CustomUser model and has max_length error messages of first_name and last_name set. realestate\auth2\forms.py:

class RegisterForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ["email", "phone", "first_name", "last_name", "birth_date"]
        error_messages = {
            "email": {"invalid": _("email.email"), "max_length": _("field.max.string").format(field=__("email"), max=255)},
            "first_name": {"max_length": _("field.max.string").format(field=__("first_name"), max=255)}, # it should override default message of existing MaxLengthValidator
            "last_name": {"max_length": _("field.max.string").format(field=__("last_name"), max=255)}, # it should override default message of existing MaxLengthValidator
        }
        widgets = {"birth_date": forms.DateInput(attrs={"type": "date"})}

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

        # ...

        # 2 Input validation & sanitization
        for field in self.fields:
            if field != "password2":
                self.fields[field].error_messages["required"] = _("field.required").format(field=_(field))

        self.fields["password1"].validators.append(PasswordValidator())
        self.fields["password2"].required = False
        self.fields["phone"].validators.append(PhoneValidator(_("phone.regex")))
        self.fields["first_name"].validators.append(AlphaValidator(_("field.alpha").format(field=__("first_name"))))
        self.fields["last_name"].validators.append(AlphaValidator(_("field.alpha").format(field=__("last_name"))))
        self.fields["birth_date"].validators.append(AdultValidator(_("birth_date.adult")))

        # Printing form fields
        for field in self.fields:
            print({
                "field": field,
                "validators": self.fields[field].validators,
                "error_messages": self.fields[field].error_messages
            })

        print()

CustomUser has CharFields with specified maximum lengths: realestate\users\models.py:

class CustomUser(AbstractUser):
    username = None
    email = models.EmailField(max_length=255, unique=True)
    phone = models.CharField(max_length=15, unique=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    birth_date = models.DateField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

The template (excerpt):

<div class="col-12">
            <div class="input-group">
              <div class="form-floating">
                {{ form.first_name }}
                <label for="first_name">Ime</label>
              </div>

              <div class="form-floating">
                {{ form.last_name }}
                <label for="last_name">Prezime</label>
              </div>
            </div>

            <div class="row row-cols-2 g-0">
              {% if form.first_name.errors or form.last_name.errors %}
                <span class="col form-text text-danger">{{ form.first_name.errors.0 }}</span>
              {% endif %}
              
              {% if form.first_name.errors or form.last_name.errors %}
                <span class="col form-text text-danger">{{ form.last_name.errors.0 }}</span>
              {% endif %}
            </div>
          </div>

I printed the form fields and its validators and error messages to console.

{'field': 'first_name', 'validators': [<django.core.validators.MaxLengthValidator object at 0x0000029123170D70>, <django.core.validators.ProhibitNullCharactersValidator object at 0x00000291230B39D0>, <globals.validators.AlphaValidator object at 0x00000291236F96D0>], 'error_messages': {'required': 'Polje ime je obavezno.', 'max_length': 'Ime ne sme imati više od 255 karaktera.'}}
{'field': 'last_name', 'validators': [<django.core.validators.MaxLengthValidator object at 0x0000029123170DD0>, <django.core.validators.ProhibitNullCharactersValidator object at 0x00000291230B3A70>, <globals.validators.AlphaValidator object at 0x000002912381E780>], 'error_messages': {'required': 'Polje prezime je obavezno.', 'max_length': 'Prezime ne sme imati više od 255 karaktera.'}}

If these fields already have MaxLengthValidators, their messages should be overridden with the ones from error_messages. When I submit the form with first_name longer than 255, the new max_length error message does not show. I entered SlAQgECJZYdNBxpdBcWTVwIteYLcavXcBdwNJUSaQDcoJhKnFbmfZGtoVMuErstpFeExSfcFxjxiuFvParFfWTtdSNXtvjwwCJhkDCmqKnFQbGixeesvvPenAHtQxgUkSdkBuUgasThLyoBWPjnwXqLoHOhrkGpdcDuekxFPCDseGHFfvZpuUvrImKqNvECnabQZkpudPyxpRwjSREYbmsclBtRTFKlLZBYSNCprVVSgkIokzFJkEMnQizaKyER, which has 256 characters, and it somehow passed.

No error message for input longer than 255 characters

This happens unless I append additional MaxLengthValidator to the field's validators in the constructor

self.fields["first_name"].validators.extend([AlphaValidator(_("field.alpha").format(field=__("first_name"))), MaxLengthValidator(255)])
self.fields["last_name"].validators.extend([AlphaValidator(_("field.alpha").format(field=__("last_name"))), MaxLengthValidator(255)])

This works and the max_length error message from error_messages shows, but then the field has two MaxLengthValidators.

{'field': 'first_name', 'validators': [<django.core.validators.MaxLengthValidator object at 0x00000275F08A0D70>, <django.core.validators.ProhibitNullCharactersValidator object at 0x00000275F07E79D0>, <globals.validators.AlphaValidator object at 0x00000275F09C8050>, <django.core.validators.MaxLengthValidator object at 0x00000275F0F405F0>], 'error_messages': {'required': 'Polje ime je obavezno.', 'max_length': 'Ime ne sme imati više od 255 karaktera.'}}
{'field': 'last_name', 'validators': [<django.core.validators.MaxLengthValidator object at 0x00000275F08A0DD0>, <django.core.validators.ProhibitNullCharactersValidator object at 0x00000275F07E7A70>, <globals.validators.AlphaValidator object at 0x00000275F0DE1310>, <django.core.validators.MaxLengthValidator object at 0x00000275F0F40530>], 'error_messages': {'required': 'Polje prezime je obavezno.', 'max_length': 'Prezime ne sme imati više od 255 karaktera.'}}

What's stopping me from overriding error messages of existing MaxLengthValidators?

that is because field.error_messages and MaxLengthValidator.message are different things. Setting field.error_messages["max_length"] does not automatically modify the message property of an existing MaxLengthValidator instance

both are treated like seperate objects when the error is occuring from MaxLengthValidator then the message displayed is the one stored inside that validator

Вернуться на верх