【问题标题】:Customizing ModelSerializer error message is being ignored自定义 ModelSerializer 错误消息被忽略
【发布时间】:2021-01-11 18:13:27
【问题描述】:

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

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} 个字符。”代替?

【问题讨论】:

  • field 在你的__init__ 中来自哪里?
  • @Ivan 抱歉,在复制粘贴我的代码时,我不小心删除了这一行:“for field in self.fields:”。我编辑了我的帖子并现在添加了该行。更有意义吗?
  • 你使用的是什么版本的 Django 和 DRF?
  • 您找到消息的来源了吗?
  • @Ivan 我正在使用 Django 1.8 和 DRF 3.2.4。您的答案是正确的,它使用了来自 MaxLengthValidator 的错误消息。我的 UserSerializer 继承自 SetCustomErrorMessagesMixin 并且在该类中 MaxLengthValidator 被覆盖。但尽管如此,实际上显示的是 MaxLengthValidator 而不是“%s 不能有超过 {max_length} 个字符。'%field”

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


【解决方案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 以在消息中添加字段名称。

【讨论】:

  • 我明白你的意思。快速的问题:只是澄清一下,当我用以下内容覆盖错误消息时:“self.fields[field].error_messages['max_length'] = '%s cannot have more than {max_length} characters.'%field”,什么我正在做的是覆盖 DRF 序列化器字段验证器吗?当我使用您发布的代码时,我正在覆盖 Django 模型字段验证器?
  • 不,我覆盖了序列化器字段(我什至在我的代码中有一个导入表明这一点)。此外,如果您想要带有字段名称的消息,您可能还需要覆盖 __init__s。
猜你喜欢
  • 1970-01-01
  • 2019-06-19
  • 2010-10-04
  • 2016-12-03
  • 1970-01-01
  • 1970-01-01
  • 2018-10-26
  • 1970-01-01
  • 2010-09-10
相关资源
最近更新 更多