django rest 框架:从序列化器 validate() 方法设置字段级错误

Posted

技术标签:

【中文标题】django rest 框架:从序列化器 validate() 方法设置字段级错误【英文标题】:django rest framework: set field-level error from serializer validate() method 【发布时间】:2015-03-26 14:34:25 【问题描述】:

我有一个序列化程序,它根据其他字段的值验证字段,在错误响应中,我想将每个字段错误显示为字段错误,而不是显示“non_field_errors”下的所有内容,如果我会发生这种情况将在对象级验证方法中引发 ValidationError。下面是我要达到的目标的图示:

MySerializer(ModelSerializer):
    ...
    def validate(self, data):
        field_val1 = data['field_val1']
        field_val2 = data['field_val2']
        if not self._is_field_valid(field_val1, field_val2):
            # The below line is how I would do what I want with Django
            # Forms, however, it's not valid in DRF
            self._errors['field_val1'] = 'this field is not valid'

所需的错误响应是:

'field_val1': ['this field is not valid']

【问题讨论】:

【参考方案1】:

与@Jkk.jonah 的回答类似,这会引发ValidationError,但它会重用原始异常文本而无需重新实现翻译:

try:
    serializer.fields['field_val1'].fail('required')
except ValidationError as exc:
    raise ValidationError(
        'field_val1': exc.detail,
    )

默认情况下(即在rest_framework.fields.Field 类上),可用的键是:

default_error_messages = 
    'required': _('This field is required.'),
    'null': _('This field may not be null.')

子类可以在那里添加自己的错误消息(SerializerField 的子类)。

顺便说一句,新的错误消息将自动与现有(继承的)消息合并 - 不会像预期的那样被覆盖。

【讨论】:

使用内置的错误消息对我来说很棒,因为翻译已经存在了。【参考方案2】:

如果您在 DRF 中使用内置验证器(实际上是 django 核心验证器),您必须使用 get_error_detail drf 用于此目的的函数预处理来自验证器的 django ValidationError。

def _validate_min_value(self, data, key):
        try:
            MinValueValidator(Decimal('0.01'))(data.get(key))
        except ValidationErrorDjango as exc:
            raise ValidationError(
                key: get_error_detail(exc)
            )

注意 ValidationErrorDjango 是来自 django.core.exceptions 的 ValidationError,而 ValidationError 是来自 rest_framework.exceptions 的一个

【讨论】:

【参考方案3】:

如果您有适用于所有字段的逻辑,您仍然可以通过执行以下操作获得所需的结果:

def validate(self, data):
    for key, value in data.items():
        # checks if value is empty
        if not value:
            raise serializers.ValidationError(key: "This field should not be left empty.")

    return data

【讨论】:

【参考方案4】:

我想通了,在“BaseSerializer”部分文档的this 页面上,有一个示例显示 ValidationError 可以在初始化时采用字典参数。

如果我 raise ValidationError('field_val1': ['this field is not valid']) 我得到我想要的 JSON 响应。

【讨论】:

也可以很好地模仿“此字段为必填项”的响应。 @MarkMishyn 不需要,但它是 Django 设置的约定,然后是 Rest Framework,将字段错误作为错误列表。但实际决定如何支持它们取决于您的前端/客户端逻辑。 请注意,这样做您还必须自己处理翻译,这与@frnhr 的回答不同。

以上是关于django rest 框架:从序列化器 validate() 方法设置字段级错误的主要内容,如果未能解决你的问题,请参考以下文章

django rest框架嵌套模型序列化器

Django Haystack 结果到 Django Rest 框架序列化器

Django Rest 框架嵌套序列化器

django rest框架json序列化器

django double left join + django rest 框架序列化器

python Django Rest_Framework框架 模型类序列化器(ModelSerializer)详解(图文并茂版)