How do I use error_messages on models in Django
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()
orerrors
), 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'})
Related videos on Youtube
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, 2022Comments
-
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 about 13 yearsI 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 about 13 yearsHmm, it works for me! Care to post your code? I'm updating mine to show my shell session just now.
-
Joelbitar about 13 yearsThat 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 about 13 yearsEhh, 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)