Gettext does not translate validation error messages in __init__

I am making a real estate Django app in my language (Serbian). I set the project language into Serbian.

realestate\settings.py:

# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/
LANGUAGE_CODE = "sr"

LANGUAGES = [
  ("sr", "Serbian"),
  ("en", "English")
]

LOCALE_PATHS = (BASE_DIR / "locale",)

TIME_ZONE = "Europe/Belgrade"
USE_I18N = True
USE_TZ = True

I made the translations in a PO file and compiled them with py manage.py compilemessages. I used simple message IDs because I’d rather not have them be literally translated messages into English.

locale\sr\LC_MESSAGES\django.po:

# General rules
msgid "field.required"
msgstr "Polje {field} adresa je obavezno."
msgid "field_alpha"
msgstr "Polje {field} mora sadržati samo slova."
msgid "field.integer"
msgstr "Polje {field} mora biti ceo broj."
msgid "field.date"
msgstr "Polje {field} mora biti ispravan datum."

# User
msgid "email.email"
msgstr "Polje Imejl adresa mora biti ispravna imejl adresa."

msgid "password2.confirmed"
msgstr "Potvrda polja Šifra se ne podudara."

msgid "phone.regex"
msgstr "Polje Broj telefona mora biti ispravan broj telefona."

msgid "birth_date.adult"
msgstr "Osoba mora biti punoletna."

# User field names
msgid "email"
msgstr "imejl adresa"
msgid "password1"
msgstr "šifra"
msgid "password2"
msgstr "potvrda šifre"
msgid "password"
msgstr "šifra"
msgid "curr_password"
msgstr "trenutna šifra"
msgid "phone"
msgstr "broj telefona"
msgid "first_name"
msgstr "ime"
msgid "last_name"
msgstr "prezime"
msgid "birth_date"
msgstr "datum rođenja"

I translate validation error messages in forms such as RegisterForm and custom validators with gettext_lazy as _.

auth2\forms.py:

# 4 Authentication & authorization
class RegisterForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ["email", "password1", "password2", "phone", "first_name", "last_name", "birth_date"]
        widgets = {"birth_date": forms.DateInput(attrs={"type": "date"})}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 2 Input validation & sanitization
        self.fields["email"].validators = [EmailValidator(message=_("email.email"))]
        self.fields["phone"].validators = [RegexValidator(regex=r"^\+381 \d{2} \d{6,7}$", message=_("phone.regex"))]
        self.fields["first_name"].validators = [AlphaValidator(message=_("field.alpha").format(field=_("first_name")))]
        self.fields["last_name"].validators = [AlphaValidator(message=_("field.alpha").format(field=_("last_name")))]
        self.fields["birth_date"].validators = [AdultValidator()]

        for field in self.fields:
            self.fields[field].widget.attrs["class"] = "form-control"
            # 2 Input validation & sanitization
            self.fields[field].error_messages = {"required": _("field.required").format(field=_(field))}
        
    # 2 Input validation & sanitization
    def clean_password2(self):
        pass1 = self.cleaned_data["password1"]
        pass2 = self.cleaned_data["password2"]

        if pass1 and pass2 and pass1 != pass2:
            raise forms.ValidationError(_("password2.confirmed"))

        return pass2

realestate\validators.py:

class AlphaValidator(RegexValidator):
    regex = r"/[a-zA-Z]*/"

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

class AdultValidator(BaseValidator):
    def __init__(self, limit_value=18, message=None):
        super().__init__(limit_value, message)

    def __call__(self, value: date):
        today = date.today()
        print(value)
        age = today.year - value.year - ((today.month, today.day) < (value.month, value.day))

        if age < self.limit_value:
            raise ValidationError(_("birth_date.adult").format(_("birth_date")))

The template file: Register form HTML - Pastebin.com . When I click submit, validation error messages inside __init__ do not get translated. Message IDs show up in the website instead of message strings.

Error messages do not get translated

But if I place some required error messages in the `Meta` class of the form, they get translated.

class RegisterForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ["email", "password1", "password2", "phone", "first_name", "last_name", "birth_date"]
        error_messages = {
            "email": {"required": _("field.required").format(field=_("email"))},
            "phone": {"required": _("field.required").format(field=_("phone"))},
            "first_name": {"required": _("field.required").format(field=_("first_name"))},
            "last_name": {"required": _("field.required").format(field=_("last_name"))},
            "birth_date": {"required": _("field.required").format(field=_("birth_date"))}
        }
        widgets = {"birth_date": forms.DateInput(attrs={"type": "date"})}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 2 Input validation & sanitization
        self.fields["password1"].error_messages = {"required": _("field.required").format(field=_("password1"))}
        self.fields["password2"].error_messages = {"required": _("field.required").format(field=_("password2"))}
        self.fields["email"].validators = [EmailValidator(message=_("email.email"))]
        self.fields["phone"].validators = [RegexValidator(regex=r"^\+381 \d{2} \d{6,7}$", message=_("phone.regex"))]
        self.fields["first_name"].validators = [AlphaValidator(message=_("field.alpha").format(field=_("first_name")))]
        self.fields["last_name"].validators = [AlphaValidator(message=_("field.alpha").format(field=_("last_name")))]
        self.fields["birth_date"].validators = [AdultValidator()]

Error messages get translated except password error messages

Error messages get translated except some

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