When the user submits a form to the back end passing a JSON user object, this is the view which handles it:
class user_list(APIView):
"""
Create a new user.
"""
def post(self, request):
serializer = UserSerializer(data=request.DATA)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
My issue is, if the user does not fill in a certain field in the form, the error message which DRF sends to the front end is "This field is required". Is there a way for me to change it so that for all fields, the error message is "{ fieldname } is required."?
This is my serializers.py:
from rest_framework import serializers
from django.contrib.auth.models import User
from CMSApp.mixins import SetCustomErrorMessagesMixin
from django.utils.translation import gettext as _
from rest_framework.validators import UniqueValidator
from django.core.validators import RegexValidator
class UserSerializer(SetCustomErrorMessagesMixin, serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'password', 'email', 'userextended')
extra_kwargs = {
'password': {
'write_only': True,
}
}
custom_error_messages_for_validators = {
'username': {
UniqueValidator: _('This username is already taken. Please try again.'),
RegexValidator: _('Invalid username')
}
}
def create(self, validated_data):
user = User.objects.create_user(
email = validated_data['email'],
username = validated_data['username'],
password = validated_data['password'],
)
return user
and this is SetCustomErrorMessageMixin:
class SetCustomErrorMessagesMixin:
"""
Replaces built-in validator messages with messages, defined in Meta class.
This mixin should be inherited before the actual Serializer class in order to call __init__ method.
Example of Meta class:
>>> class Meta:
>>> model = User
>>> fields = ('url', 'username', 'email', 'groups')
>>> custom_error_messages_for_validators = {
>>> 'username': {
>>> UniqueValidator: _('This username is already taken. Please, try again'),
>>> RegexValidator: _('Invalid username')
>>> }
>>> }
"""
def __init__(self, *args, **kwargs):
# noinspection PyArgumentList
super(SetCustomErrorMessagesMixin, self).__init__(*args, **kwargs)
self.replace_validators_messages()
def replace_validators_messages(self):
for field_name, validators_lookup in self.custom_error_messages_for_validators.items():
# noinspection PyUnresolvedReferences
for validator in self.fields[field_name].validators:
if type(validator) in validators_lookup:
validator.message = validators_lookup[type(validator)]
@property
def custom_error_messages_for_validators(self):
meta = getattr(self, 'Meta', None)
return getattr(meta, 'custom_error_messages_for_validators', {})
Lastly, this is my models.py (the UserExtended model):
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Color(models.Model):
colorName = models.CharField(max_length=50, unique=True)
colorCode = models.CharField(max_length=10, unique=True)
class UserExtended(models.Model):
user = models.OneToOneField(User, related_name="userextended")
color = models.ForeignKey(Color)
You can override the __init__()
method of UserSerializer
to change the default error message for a required
field .
We will iterate over the fields
of the serializer and change the value of default error_messages
value for the required
key.
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'] = '%s field is required'%field # set the custom error message
...