Custom error messages not working in Django ModelForm
Asked Answered
G

1

1

I have a ModelForm and I want to customize some of the error messages for required fields. Some of the customized error messages work, but some don't. Here is my code:

error_messages = {
    'photo': {
        'required': _("A profile picture is required."),
    },
    'height': {
        'required': _("Your height is required."),
    },
    'diet': {
        'required': _("Your diet is required."),  # ~~~~ TODO: not working.
    },
    'smoking_status': {
        'required': _("Your smoking status is required."),  # ~~~~ TODO: not working.
    },
    'relationship_status': {
        'required': _("Your relationship status is required."),  # ~~~~ TODO: not working.
    },
    **{to_attribute(name='profile_description', language_code=language_code): {
        'required': _("Please write a few words about yourself."),
    } for language_code, language_name in django_settings.LANGUAGES},
    **{to_attribute(name='city', language_code=language_code): {
        'required': _("Please write where you live."),  # ~~~~ TODO: not working.
    } for language_code, language_name in django_settings.LANGUAGES},
    **{to_attribute(name='children', language_code=language_code): {
        'required': _("Do you have children? How many?"),
    } for language_code, language_name in django_settings.LANGUAGES},
    **{to_attribute(name='more_children', language_code=language_code): {
        'required': _("Do you want (more) children?"),
    } for language_code, language_name in django_settings.LANGUAGES},
    **{to_attribute(name='match_description', language_code=language_code): {
        'required': _("Who is your ideal partner?"),
    } for language_code, language_name in django_settings.LANGUAGES},
    'gender_to_match': {
        'required': _("Gender to match is required."),  # ~~~~ TODO: not working.
    },
    'min_age_to_match': {
        'required': _("Minimal age to match is required."),
    },
    'max_age_to_match': {
        'required': _("Maximal age to match is required."),
    },
    'diet_match': {
        'required': _("Diet match is required."),
    },
    'smoking_status_match': {
        'required': _("Smoking status match is required."),
    },
    'relationship_status_match': {
        'required': _("Relationship status match is required."),
    },
}

https://github.com/speedy-net/speedy-net/blob/staging/speedy/match/accounts/forms.py#L100-L149

I marked the custom error messages which are not working with # ~~~~ TODO: not working.. The others are working.

Any suggestions?

Guiltless answered 9/8, 2019 at 6:3 Comment(3)
You're overriding these fields by either defining them directly in the top of your form or in the __init__ method of your form. The error_messages Meta option only works for fields that are not overridden (it's just used by the ModelForm to create the fields automatically from the Model).Charitycharivari
@Charitycharivari How do I override these error messages? I searched and found that they should be in class Meta, isn't it correct?Guiltless
OK, I understand. Please see my answer below.Guiltless
G
0

OK, I found out that I have to define these error messages when I declare the fields or the widgets:

photo = forms.ImageField(required=False, widget=CustomPhotoWidget, label=_('Add profile picture'), error_messages={'required': _("A profile picture is required.")})
diet = forms.ChoiceField(widget=forms.RadioSelect(), label=_('My diet'), error_messages={'required': _("Your diet is required.")})
smoking_status = forms.ChoiceField(widget=forms.RadioSelect(), label=_('My smoking status'), error_messages={'required': _("Your smoking status is required.")})
relationship_status = forms.ChoiceField(widget=forms.RadioSelect(), label=_('My relationship status'), error_messages={'required': _("Your relationship status is required.")})
gender_to_match = forms.MultipleChoiceField(choices=User.GENDER_CHOICES, widget=forms.CheckboxSelectMultiple, error_messages={'required': _("Gender to match is required.")})
# ~~~~ TODO: define all the languages and not just hard-code languages like below.
_city = forms.CharField(label=_('City or locality'), max_length=120, error_messages={'required': _("Please write where you live.")})
city_en = _city
city_he = _city

https://github.com/speedy-net/speedy-net/blob/staging/speedy/match/accounts/forms.py#L58-L66

The error message can also be customized in the __init__ method:

    if (to_attribute(name='profile_description') in self.fields):
        self.fields[to_attribute(name='profile_description')].error_messages = {'required': pgettext_lazy(context=self.instance.user.get_gender(), message="Please write a few words about yourself.")}
    if (to_attribute(name='city') in self.fields):
        self.fields[to_attribute(name='city')].error_messages = {'required': pgettext_lazy(context=self.instance.user.get_gender(), message="Please write where you live.")}
    if (to_attribute(name='children') in self.fields):
        self.fields[to_attribute(name='children')].label = pgettext_lazy(context=self.instance.user.get_gender(), message='Do you have children? How many?')
        self.fields[to_attribute(name='children')].error_messages = {'required': pgettext_lazy(context=self.instance.user.get_gender(), message="Do you have children? How many?")}
    if (to_attribute(name='more_children') in self.fields):
        self.fields[to_attribute(name='more_children')].label = pgettext_lazy(context=self.instance.user.get_gender(), message='Do you want (more) children?')
        self.fields[to_attribute(name='more_children')].error_messages = {'required': pgettext_lazy(context=self.instance.user.get_gender(), message="Do you want (more) children?")}
    if (to_attribute(name='match_description') in self.fields):
        self.fields[to_attribute(name='match_description')].label = pgettext_lazy(context=self.instance.get_match_gender(), message='My ideal match')
        self.fields[to_attribute(name='match_description')].error_messages = {'required': pgettext_lazy(context=self.instance.get_match_gender(), message="Who is your ideal partner?")}

https://github.com/speedy-net/speedy-net/blob/staging/speedy/match/accounts/forms.py#L170-L182

Guiltless answered 10/8, 2019 at 3:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.