How do I use error_messages on models in Django

16,206

Solution 1

You're right, those docs are not very useful. It's a recent addition after all!

My guess is that the normal usage of error_messages is for ModelForms, so I'd look here for a list of acceptable error keys per field: http://docs.djangoproject.com/en/dev/ref/forms/fields/#error-messages

But, if you want to be really safe and not assume anything...

The most reliable way for now is going to be looking at the source at django/db/models/fields/__init__.py where you'll see each of the default_error_messages that can be specified and the actual calls to self.error_messages['invalid']

# Field (base class)

default_error_messages = {
    'invalid_choice': _(u'Value %r is not a valid choice.'),
    'null': _(u'This field cannot be null.'),
    'blank': _(u'This field cannot be blank.'),
}

# AutoField  
    default_error_messages = {
        'invalid': _(u'This value must be an integer.'),
    }

Here's the doc on model validation: http://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects

Update:

Just tested this in a shell session and it appears to be working. Whats up?

I just defined a simple model:

class SubscriptionGroup(models.Model):
    name = models.CharField(max_length=255, error_messages={'blank': 'INVALID!!11', 'null': 'NULL11!'})

# shell
>>> s = SubscriptionGroup()
>>> s.full_clean()
ValidationError: {'name': [u'INVALID!!11']}

Solution 2

(Bit late to this one, but I have been through the same issues myself, so using this as a note_to_self as much as anything.)

You can specify error_messages on both models and modelforms. The keys you should / can use are defined here for the form fields. The issue seems to be (to me) the inter-relationship between forms and the related model, and which error message appears, and when. The key to this is understanding that forms and models are actually very loosely-coupled, and that there really is no magic happening.

If you have a model field called 'quote', with a max_length of 140, and a modelform associated with this model, the error messages will work thus:

  • If you don't explicitly add a max_length attribute to the modelform, and then validate the form (calling is_valid() or errors), the error message that comes back will be from the model.
  • If you add a set of error_messages ('required','max_length') to the model, these will appear in the errors collection.
  • If you add a set of error_messages to the modelform, they will not appear, as it is the model that is failing validation, not the form.
  • If you then add a max_length attribute to the modelform, you will see the modelform errors surfacing (and overriding the model error_messages.)

So - fairly simple in summary - the error messages map to the object that is being validated - which can be either the model or the modelform.

Solution 3

I tried. It will not work if you defined it in models. You must define error_messages in your forms like this

name = forms.CharField(error_messages={'required': 'this field is required'})
Share:
16,206

Related videos on Youtube

Joelbitar
Author by

Joelbitar

I like programming, I also like beer. Big fan of Android, Python and free software. I wish there were more hours on a day to write more code, there is always some project to finish.

Updated on May 17, 2022

Comments

  • Joelbitar
    Joelbitar almost 2 years

    I understand form the documentation http://docs.djangoproject.com/en/dev/ref/models/fields/ that you can add error_messages to a model field and supply your own dict of error messages. However, what are they keys of the dict you are supposed to pass?

    class MyModel(models.Model):
       some_field = models.CharField(max_length=55, error_messages={'required': "My custom error"})
    

    If it is easier to do this on the modelform that is used that would also work, however. I would rather not have to create explicitly creating each field and their type again. This is what I was trying to avoid:

    class MyModelForm(forms.ModelForm):
        some_field = forms.CharField(error_messages={'required' : 'Required error'})
    

    Update 2: Test code used in my project

    My Model:

    class MyTestModel(models.Model):
        name = models.CharField(max_length=127,error_messages={'blank' : 'BLANK','required' : 'REQUIRED'})
    

    My Form:

    class EditTestModel(ModelForm):
        class Meta:
            model = MyTestModel
    

    My View:

    tf = EditTestModel({'name' : ''})
    
    print tf.is_valid() # prints False
    print tf.full_clean() # prints None
    print tf # prints the form, with a <li> error list containg the error "This field is required"
    
    
    <tr><th><label for="id_name">Name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input id="id_name" type="text" name="name" maxlength="127" /></td></tr>
    
  • Joelbitar
    Joelbitar about 13 years
    I took a peek in the source files you mentioned and came to the same conclusion. As you see in my example I pass a key 'required' in error_messages but it does not work. Maby I've done something wrong somewhere, I'll have to continue testing. Thank you!
  • Yuji 'Tomita' Tomita
    Yuji 'Tomita' Tomita about 13 years
    Hmm, it works for me! Care to post your code? I'm updating mine to show my shell session just now.
  • Joelbitar
    Joelbitar about 13 years
    That is so wierd, I'v added my code that is used in the app. For now I'm using the method that I'v tried to avoid. However, your example clearly works and is the right way to do it.
  • Yuji 'Tomita' Tomita
    Yuji 'Tomita' Tomita about 13 years
    Ehh, despite what I wrote in a sentence in my answer, it looks like this is expected behavior for modelforms not to inherit model cleaning validators. code.djangoproject.com/ticket/13693 (my method is using model validation, not form validation)