9

这是我的 serializers.py(我想为内置的 User 模型创建一个序列化程序):

from rest_framework import serializers

from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ('username', 'password', 'email', )

我知道 Django Rest Framework 有它自己的字段验证器,因为当我尝试使用已经存在的用户名创建用户时,它会引发错误提示:

{'username': [u'This field must be unique.']}

我想自定义错误消息并使其显示“此用户名已被占用。请重试”而不是“此字段必须是唯一的”。

它还有一个内置的正则表达式验证器,因为当我创建一个带有感叹号的用户名时,它会说:

{'username': [u'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.']}

我想自定义正则表达式验证器,使其只显示“无效的用户名”。

如何自定义每个字段具有的所有错误消息?

注意:根据这篇文章:Django Rest Framework 序列化程序中的自定义错误消息我可以做:

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'

但是对于“唯一”和“正则表达式”验证器,我该怎么办?我试着做

self.fields['username'].error_messages['regex'] = u'My custom required msg'

self.fields['username'].error_messages['validators'] = u'My custom required msg'

但都没有奏效。

4

2 回答 2

6

为了替换唯一或正则表达式错误消息,您应该更改message相应验证器对象的成员。这可以使用单独的 mixin 类来完成:

from django.core.validators import RegexValidator
from rest_framework.validators import UniqueValidator
from django.utils.translation import ugettext_lazy as _


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

然后你可以继承这个 mixin 并更新Meta类:

class UserSerializer(SetCustomErrorMessagesMixin, serializers.HyperlinkedModelSerializer):
    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')
            }
        }
于 2015-06-01T05:15:18.187 回答
1

您也可以只自定义您的语言翻译,请看这里:

https://docs.djangoproject.com/en/3.2/topics/i18n/translation/#message-files

您所要做的就是创建消息文件,在其中更改翻译并将您的消息编译成 .mo 文件。

这种方法并不像我看起来的那样不可接受。看这里:

https://www.django-rest-framework.org/topics/internationalization/

DRF 文档说,它的常见做法是通过翻译自定义错误消息(您自己的和默认的)。

我对那些想尝试上述路径的人的提示:

  1. 制作默认的 django.po 文件。大多数默认错误都会出现。
  2. 如果您使用的是 DRF,请打开此文件https://raw.githubusercontent.com/encode/django-rest-framework/master/rest_framework/locale/en_US/LC_MESSAGES/django.po,选择您要自定义的错误并仅将该错误复制到上面的 django.po 文件中。
  3. 自定义它。
  4. 编译它。

(!)注意确保您的翻译文件完全命名为 django.po,而不是 mylovelydjango.po,不是 myproject.po,而是 EXACTLY django.po,否则将不起作用。

于 2021-11-03T09:26:29.270 回答