Custom error messages in Django Rest Framework serializer
EDIT: I see that this question still receives some views, so it is important to note that there's another approach, much cleaner than the original answer I posted here.
You can just use the extra_kwargs attribute of the serializer's Meta class, like so:
class UserSerializer(ModelSerializer):
class Meta:
model = User
extra_kwargs = {"username": {"error_messages": {"required": "Give yourself a username"}}}
Original answer:
Using @mariodev 's answer I created a new class in my project that does that:
from rest_framework.serializers import ModelSerializer, ModelSerializerOptions
class CustomErrorMessagesModelSerializerOptions(ModelSerializerOptions):
"""
Meta class options for CustomErrorMessagesModelSerializerOptions
"""
def __init__(self, meta):
super(CustomErrorMessagesModelSerializerOptions, self).__init__(meta)
self.error_messages = getattr(meta, 'error_messages', {})
class CustomErrorMessagesModelSerializer(ModelSerializer):
_options_class = CustomErrorMessagesModelSerializerOptions
def __init__(self, *args, **kwargs):
super(CustomErrorMessagesModelSerializer, self).__init__(*args, **kwargs)
# Run through all error messages provided in the Meta class and update
for field_name, err_dict in self.opts.error_messages.iteritems():
self.fields[field_name].error_messages.update(err_dict)
The first one gives the possibility to add a new Meta
class attribute to the serializer as with the ModelForm
.
The second one inherits from ModelSerializer
and uses @mariodev's technique to update the error messages.
All is left to do, is just inherit it, and do something like that:
class UserSerializer(CustomErrorMessagesModelSerializer):
class Meta:
model = User
error_messages = {"username": {"required": "Give yourself a username"}}
In your serializer:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
def __init__(self, *args, **kwargs):
super(UserSerializer, self).__init__(*args, **kwargs)
self.fields['username'].error_messages['required'] = u'My custom required msg'
Please notice that some error messages consist of %s
placeholders like:
'invalid': _("'%s' value must be either True or False."),
for BooleanField
.
So you need to go over default_error_messages
part in each field type in the DRF's fields.py
, to use it properly.
I tried to create a simple Serializer
rather than a ModelSerializer
. Probably because of that the accepted answer with extra_kwargs
by Gabriel Amram didn't work for me. Another top answer by @mariodev did work but I was looking for a more elegant solution and found one. Turns out that the Field
class accepts error_messages
as a parameter, which is a dictionary that overrides the default error messages. Here is the reference to the docs. It's the same format as described in the accepted answers. Here is an example:
from rest_framework import serializers
class MySerializer(serializers.Serializer):
client_id = serializers.IntegerField(required=True, error_messages={'required': 'Custom error message'})
unique
seemed to be ignored from error_messages
, so I had to take a different approach.
email = serializers.EmailField(validators=[
UniqueValidator(
queryset=models.Client.objects.all(),
message="My custom error",
)]
)
It's simpler (yet less flexible, less reusable) than @gabriel-amram's, but far less hacky than @mariodev's.
Another approach for UniqueValidator (for using with ModelSerializer):
def __init__(self, *args, **kwargs):
super(UserSerializer, self).__init__(*args, **kwargs)
# Find UniqueValidator and set custom message
for validator in self.fields['email'].validators:
if isinstance(validator, validators.UniqueValidator):
validator.message = _('This email already exist on this site')