【问题标题】:How to change "This field is required" error message for a DjangoRestFramework serializer?如何更改 DjangoRestFramework 序列化程序的“此字段是必需的”错误消息?
【发布时间】:2021-12-03 03:10:00
【问题描述】:

当用户通过 JSON 用户对象向后端提交表单时,这是处理它的视图:

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)

我的问题是,如果用户没有填写表单中的某个字段,DRF 发送到前端的错误消息是“This field is required”。有没有办法让我改变它,以便对于所有字段,错误消息都是“需要 { fieldname }。”?

这是我的 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

这是 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', {})

最后,这是我的 models.py(UserExtended 模型):

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)

【问题讨论】:

    标签: django django-rest-framework django-serializer


    【解决方案1】:

    您可以覆盖UserSerializer__init__() 方法来更改required 字段的默认错误消息。

    我们将遍历序列化程序的 fields 并更改 required 键的默认值 error_messagesvalue。

    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
    
        ...
    

    【讨论】:

    • 有趣。谢谢。您是否知道我会覆盖序列化程序的 init 方法以更改错误消息记录在任何地方? (只是这样我可以阅读它,并希望了解更多关于它的信息)。
    • 我不认为这种方法记录在他们的网站上。但是,是的,如果您想覆盖验证器的默认错误消息,您可以查看此DRF link。另外,我建议的另一个选择是检查 rest_framework/fields.py 文件中的 DRF 源代码。在那里我们可以看到每个字段都附加了.error_messages 字典,我们可以使用它来覆盖默认消息。
    【解决方案2】:

    对于ModelSerializer,我通常只使用extra_kwargs 属性,我发现它更具可读性和可维护性。请参阅下面的示例序列化程序,了解如何完成。

    class UserSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = User
            fields = '__all__'
            extra_kwargs = {
                "email": {
                    "error_messages": {
                        "required": "User's Email is required",
                    },
                },
                "phone": {
                    "error_messages": {
                        "required": "User's Phone is required",
                    },
                },
            }
    

    在上面的示例中,emailphone 是存在于 User 模型中的两个字段。现在,您将收到自定义消息,而不是通用的“此字段是必需的”消息。

    【讨论】:

      猜你喜欢
      • 2019-08-28
      • 2015-07-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2020-01-29
      • 2014-01-04
      • 1970-01-01
      相关资源
      最近更新 更多