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