61

I can see how to add an error message to a field when using forms, but what about model form?

This is my test model:

class Author(models.Model):
    first_name = models.CharField(max_length=125)
    last_name = models.CharField(max_length=125)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

My model form:

class AuthorForm(forms.ModelForm):
    class Meta:
        model = Author

The error message on the fields: first_name and last_name is:

This field is required

How do I change that in a model form?

7 Answers 7

62

For simple cases, you can specify custom error messages

class AuthorForm(forms.ModelForm):
    first_name = forms.CharField(error_messages={'required': 'Please let us know what to call you!'})
    class Meta:
        model = Author
Sign up to request clarification or add additional context in comments.

4 Comments

Cool thanks. I did not know what would be the result of doing that. The documentation says "Declared fields will override the default ones generated by using the model attribute" so I should be good. I would also have to set the max_field again on the model form field.
Is it really necessary to repeat field declarations in the form? How about the DRY principle django is proud of?
LOL, man, I think OP want use forms from models but not declare forms two times.
I think that with respect to the client side, being explicit is more important then DRY.
59

New in Django 1.6:

ModelForm accepts several new Meta options.

  • Fields included in the localized_fields list will be localized (by setting localize on the form field).
  • The labels, help_texts and error_messages options may be used to customize the default fields, see Overriding the default fields for details.

From that:

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ('name', 'title', 'birth_date')
        labels = {
            'name': _('Writer'),
        }
        help_texts = {
            'name': _('Some useful help text.'),
        }
        error_messages = {
            'name': {
                'max_length': _("This writer's name is too long."),
            },
        }

Related: Django's ModelForm - where is the list of Meta options?

6 Comments

i don't understand the _() surrounding the custom error message text, so i took that out. but this is the first snippet that worked for me. i'm on django 1.6. thank you, sir!
You're welcome! If you're curious, the underscore function is a common shortcut for an internationalization utility: stackoverflow.com/questions/2964244/…
I think this should be the accepted answer as it follow DRY principles. When using ModelForm, there shouldn't be a need to declare fields again and there shouldn't be a need to override methods either.
The defaults in the Meta class are only used if the fields and widgets are not defined deliberately. If they are defined deliberately, the error messages should be defined there, or in the __init__ method.
|
21

Another easy way of doing this is just override it in init.

class AuthorForm(forms.ModelForm):
    class Meta:
        model = Author

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

        # add custom error messages
        self.fields['name'].error_messages.update({
            'required': 'Please let us know what to call you!',
        })

2 Comments

This is much better solution than all other in this thread because 1) You don't have to use any extensions 2) you don't have to rewrite whole form field definition because it depends on definition of model field. +1
One note thought, you have to use it like this self.fields['name'].error_messages['required'] = 'Please let us know what to call you!' or using .update() method, otherwise you reset all other error messages.
15

I have wondered about this many times as well. That's why I finally wrote a small extension to the ModelForm class, which allows me to set arbitrary field attributes - including the error messages - via the Meta class. The code and explanation can be found here: http://blog.brendel.com/2012/01/django-modelforms-setting-any-field.html

You will be able to do things like this:

class AuthorForm(ExtendedMetaModelForm):
    class Meta:
        model = Author
        field_args = {
            "first_name" : {
                "error_messages" : {
                    "required" : "Please let us know what to call you!"
                }
            }
        }

I think that's what you are looking for, right?

2 Comments

This is a great way to do this. Certainly more DRY than redefining form fields.
@suda you aren't really redefining, you are overriding the default behavior based on the model associated. similar to changing an input to a textarea, you are overriding the default.
7

the easyest way is to override the clean method:

class AuthorForm(forms.ModelForm):
   class Meta:
      model = Author
   def clean(self):
      if self.cleaned_data.get('name')=="":
         raise forms.ValidationError('No name!')
      return self.cleaned_data

Comments

6

I have a cleaner solution, based on jamesmfriedman's answer. This solution is even more DRY, especially if you have lots of fields.

custom_errors = {
    'required': 'Your custom error message'
}

class AuthorForm(forms.ModelForm):
    class Meta:
        model = Author

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

        for field in self.fields:
            self.fields[field].error_messages = custom_errors

1 Comment

Exactly what I was looking for. This is the right way to do it.
4

You can easily check and put custom error message by overriding clean()method and using self.add_error(field, message):

def clean(self):
    super(PromotionForm, self).clean()
    error_message = ''
    field = ''
    # reusable check
    if self.cleaned_data['reusable'] == 0:
        error_message = 'reusable should not be zero'
        field = 'reusable'
        self.add_error(field, error_message)
        raise ValidationError(error_message)

    return self.cleaned_data

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.