1

这是我UserSerializer(我使用的是默认的Django用户模型):定制ModelSerializer错误信息被忽略

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

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

但“用户名太长”。来自并且怎么没有说“用户名不能超过{max_length}个字符。”代替?

+0

'field'来自'__init__'哪里? – Ivan

+0

@Ivan对不起,当复制粘贴我的代码时,我不小心删除了这一行:“for self in field.fields:”。我编辑了我的帖子,现在添加了该行。它更有意义吗? – user2719875

+0

你正在使用什么版本的Django和DRF? – Ivan

回答

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__ s来在消息中添加字段名称。

+0

我明白你的意思了。快速的问题,只是为了澄清,当我重写错误信息:“self.fields [field] .error_messages ['max_length'] ='%s不能超过{max_length}字符'%field',什么我正在重写DRF Serializer字段验证器?当我使用你发布的代码时,我重写了Django模型字段验证器? – user2719875

+0

不,我重写serialzer字段(我甚至在我的代码中有一个导入,表明这一点)。另外,如果你想要带有字段名的消息,你也可以重写'__init__'s。 – Ivan