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"),
"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, validators and error messages
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.
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? How can I override the default error messages of existing validators?