This is my UserSerializer (I'm using the default Django User model):
class UserSerializer(SetCustomErrorMessagesMixin, serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
super(UserSerializer, self).__init__(*args, **kwargs) # call the super()
for field in self.fields: # iterate over the serializer fields
self.fields[field].error_messages['required'] = 'Enter a valid %s.'%field
self.fields[field].error_messages['null'] = 'Enter a valid %s.'%field
# class CharField(Field) errors
self.fields[field].error_messages['blank'] = 'Enter a valid %s.'%field
self.fields[field].error_messages['max_length'] = '%s cannot have more than {max_length} characters.'%field
self.fields[field].error_messages['min_length'] = '%s cannot have less than {min_length} characters.'%field
class Meta:
model = User
fields = ('username', 'password', 'email',)
The problem is, when a user inputs a username which is too long, the error message is
"Username is too long."
Where is this error message coming from? I overwrote the "max_length" error message in the code above, but it does not show it. When I delete this line from my UserSerialzer:
self.fields[field].error_messages['max_length'] = '%s cannot have more than {max_length} characters.'%field
then the error message is:
"Ensure this field has no more than 30 characters."
which makes sense beause it is coming from the CharField DRF source code here: https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/fields.py
But where is "Username is too long." coming from and how come it does not say "Username cannot have more than {max_length} characters." instead?
The problem appears to be that DRF adds validators for fields during their construction and copies the error messages from field classes.
For example from rest_framework.fields.CharField.__init__
:
if self.min_length is not None:
message = self.error_messages['min_length'].format(min_length=self.min_length)
self.validators.append(MinLengthValidator(self.min_length, message=message))
So at the moment you are overwriting the messages, they are already used in the validators.
I think you can just create a yourapp.fields
module where you subclass DRF serializer fields and override their default_error_messages
, like so:
from rest_framework import fields
class CharField(fields.CharField):
default_error_messages = {
# Your messages
}
And then just switch the module you import fields from.
You might also want to override __init__
s to add field names in messages.