61
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"}}
28
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'})
- [Django]-Where should signal handlers live in a django project?
- [Django]-How can I list urlpatterns (endpoints) on Django?
- [Django]-Get the list of checkbox post in django views
26
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.
- [Django]-How do I install psycopg2 for Python 3.x?
- [Django]-Custom validation in Django admin
- [Django]-Django gives Bad Request (400) when DEBUG = False
16
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.
- [Django]-How to configure where to redirect after a log out in Django?
- [Django]-'EntryPoints' object has no attribute 'get' – Digital ocean
- [Django]-How do you know if memcached is doing anything?
6
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')
- [Django]-Altering database tables in Django
- [Django]-Best way to make Django's login_required the default
- [Django]-The QuerySet value for an exact lookup must be limited to one result using slicing. Filter error
5
I just spent an hour ripping my hair out over this, so figured I’d post an update here in case anyone else finds it useful.
I’m using djangorestframework version 3.10.3, and for whatever reason, it seems that drf no longer uses the ‘required’ key in the error_messages dict to allow customization of an error message for a missing value. Instead it uses ‘blank’.
class SampleSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = SampleModel
fields = (
'description',
)
extra_kwargs = {
'description': {'error_messages': {'blank': "Please provide a description"}},
}
- [Django]-How to make Django's DateTimeField optional?
- [Django]-Get virtualenv's bin folder path from script
- [Django]-How to limit columns returned by Django query?
4
DRF3.0 expects us to explicitly define the validators for fields if we wish to override the default model validators. This can be done by passing extra_kwargs and explicitly defining the validators for whichever field
you seem necessary. Also you can even specify your own custom validator which can be reused again for different fields or even other serializers
http://www.django-rest-framework.org/api-guide/serializers/#validation
http://www.django-rest-framework.org/api-guide/validators/#validation-in-rest-framework
# my_app/validators.py
def validate_required(value):
# whatever validation logic you need
if value == '' or value is None:
raise serializers.ValidationError('This field is required.')
# my_app/serializers.py
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
extra_kwargs = {"field1": {"validators": [validators.validate_required,]}}
- [Django]-Pypi see older versions of package
- [Django]-How do I add a placeholder on a CharField in Django?
- [Django]-How to disable Django's CSRF validation?
0
Just a note since I played with this for awhile, if you’re using something like a URLField that just adds a URLValidator, it doesn’t seem to use the error_messages
, so I did something similar to @Hugo’s answer:
class Meta:
extra_kwargs = {"url_field": {"validators": [validators.URLValidator(message="My error message")]}}
- [Django]-Django switching, for a block of code, switch the language so translations are done in one language
- [Django]-Django REST Framework – 405 METHOD NOT ALLOWED using SimpleRouter
- [Django]-How to have a Python script for a Django app that accesses models without using the manage.py shell?
0
You can create separate function in serializers.py and call it from serializer class
def checkFields(fields):
for field in fields:
fields[field].error_messages['blank']=fields[field].error_messages['required'] = 'Please enter %s'%field
- [Django]-Django Model MultipleChoice
- [Django]-Django: Get current user in model save
- [Django]-Django: Get an object form the DB, or 'None' if nothing matches
-1
This is the code that inherits the model’s error message.
There is also a module, so download it if you want.
If there’s a problem, leave it in the comments.
https://pypi.org/project/django-rest-inherits-error-messages/#files
from rest_framework import serializers
from rest_framework.relations import HyperlinkedRelatedField
from rest_framework.utils.field_mapping import get_nested_relation_kwargs
class InheritsModelSerializer(serializers.ModelSerializer):
def build_field(self, field_name, info, model_class, nested_depth):
'''
inherits the error_messages of the model
'''
result: tuple = super().build_field(field_name, info, model_class, nested_depth)
field = model_class._meta.get_field(field_name)
error_messages = field.error_messages
if error_messages:
result[1]['error_messages'] = field.error_messages
return result
- [Django]-Django Rest Framework pagination extremely slow count
- [Django]-Laravel's dd() equivalent in django
- [Django]-Readonly models in Django admin interface?