正在忽略自定义ModelSerializer错误消息

时间:2015-10-20 20:45:47

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

这是我的UserSerializer(我使用的是默认的Django用户模型):

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

问题是,当用户输入的用户名太长时,错误消息为

"Username is too long."

此错误消息来自何处?我在上面的代码中覆盖了“max_length”错误消息,但它没有显示它。当我从UserSerialzer中删除这一行时:

self.fields[field].error_messages['max_length'] = '%s cannot have more than {max_length} characters.'%field

然后错误信息是:

"Ensure this field has no more than 30 characters."

这是有道理的,因为它来自CharField DRF源代码:https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/fields.py

但是“用户名太长了”。来自,为什么不说“用户名不能超过{max_length}个字符。”代替?

1 个答案:

答案 0 :(得分:1)

问题似乎是DRF在构造过程中为字段添加验证器,并从字段类中复制错误消息。

例如来自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))

所以目前你正在覆盖这些消息,它们已经在验证器中使用了。

我认为您可以创建一个yourapp.fields模块,您可以在其中继承DRF序列化程序字段并覆盖其default_error_messages,如下所示:

from rest_framework import fields

class CharField(fields.CharField):

    default_error_messages = {
        # Your messages
    }

然后只需切换导入字段的模块。

您可能还想覆盖__init__以在消息中添加字段名称。

相关问题