回到顶部

Contents

rest_framework serializers ValidationError 错误信息自定义 key 值

开发环境

Django                  1.11.14
django-crispy-forms     1.7.0
django-filter           1.1.0
django-formtools        2.1
django-guardian         1.4.9
django-import-export    0.5.1
django-redis            4.8.0
django-reversion        2.0.10
djangorestframework     3.7.1
djangorestframework-jwt 1.11.0

原本效果

serializers.ValidationError 是原来的 key 值是字段名,想改成通用的错误名,比如:msg

提取 ValidationError

# ..\users\my_validation_error.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
@author: yinzhuoqun
@site: http://xieboke.net/
@email: yin@zhuoqun.info
@time: 2020/4/9 16:22
"""
# ..\Lib\site-packages\rest_framework\exceptions.py
from coreapi.compat import force_text
from rest_framework.exceptions import APIException, ErrorDetail
from rest_framework import status
from rest_framework.utils.serializer_helpers import ReturnList, ReturnDict
from django.utils.translation import ugettext_lazy as _


def _get_error_details(data, default_code=None):
    """
    Descend into a nested data structure, forcing any
    lazy translation strings or strings into `ErrorDetail`.
    """
    if isinstance(data, list):
        ret = [
            _get_error_details(item, default_code) for item in data
        ]
        if isinstance(data, ReturnList):
            return ReturnList(ret, serializer=data.serializer)
        return ret
    elif isinstance(data, dict):
        ret = {
            key: _get_error_details(value, default_code)
            for key, value in data.items()
        }
        if isinstance(data, ReturnDict):
            return ReturnDict(ret, serializer=data.serializer)
        return ret

    text = force_text(data)
    code = getattr(data, 'code', default_code)
    return ErrorDetail(text, code)


class MyValidationError(APIException):
    status_code = status.HTTP_400_BAD_REQUEST
    default_detail = _('Invalid input.')
    default_code = 'invalid'

    def __init__(self, detail=None, code=None):
        if detail is None:
            detail = self.default_detail
        if code is None:
            code = self.default_code

        # For validation failures, we may collect many errors together,
        # so the details should always be coerced to a list if not already.
        if not isinstance(detail, dict) and not isinstance(detail, list):
            detail = [detail]

        self.detail = _get_error_details(detail, code)

serializers.py 导入使用

from users.my_validation_error import MyValidationError

class EmailVerifySerializer(serializers.Serializer):

    email = serializers.EmailField(required=True, label="邮箱", error_messages={
        "blank": "请输入邮箱",
        "required": "请输入邮箱",
    }, help_text="请输入邮箱")


    def validate_email(self, email):
        """
        验证邮箱
        :param email:
        :return:
        """

        # 验证是否注册
        if User.objects.filter(email=email).count():
            # raise serializers.ValidationError("请输入新的邮箱或找回账户密码")
            raise MyValidationError(detail={"msg": "请输入新的邮箱或找回账户密码"})

期望效果

^_^
请喝咖啡 ×

前一篇: how to django admin changlist add myself data
下一篇: MIUI 11 默认应用入口(修改默认浏览器)
captcha