Django Rest Framework验证失败的自定义响应

时间:2017-09-09 06:48:44

标签: python django validation django-rest-framework

背景

我是Django和其他框架的新手,我正在尝试使用Django Rest Framework为移动应用程序构建一个注册和登录的API演示。

我想要

我正在使用APIViewModelSerializer,并且注册的参数和约束是

email <required, unique>,
username <required, unique>,
password <required, unique>,

在这里,我的要求侧重于异常,我想获得一个自定义错误代码,以指示哪些验证(必需或唯一)失败。

例如

当我发送参数时:

username="", (leaves it blank)
password=123, 
email="xxx@yyy.com"

这将导致required验证失败,并且JSON响应返回类似

的内容
"username": [
    "This field may not be blank."
]

但是,我希望JSON响应类似于

{
    error_code: 1,
    msg: "blah blah blah"
}

通过这种方式,移动应用可以根据error_code做任何想做的事。

问题

我发现,在框架的验证实现中,验证失败(所有字段验证失败)已经转换为纯文本并打包在一个数组中,我无法获得特定的异常(例如用户名)必需的异常),我无法在响应中生成error_code。

那么,有没有办法捕获特定的异常?

3 个答案:

答案 0 :(得分:0)

您可以使用extra_kwargs

class UserSerializer(ModelSerializer):

class Meta:
    model = User
    extra_kwargs = {"username": {"error_messages": {"required": "Give yourself a username"}}}

答案 1 :(得分:0)

在序列化程序的to_internal_value中,您可以捕获ValidatonErrors并对其进行修改。

class MySerializer(ModelSerializer):

    def to_internal_value(self, data):
        try:
            return super().to_internal_value(data)
        except serializers.ValidationError as err:
            # do something with the error messages
            # reraise with the modified ValidationError
            raise err

http://www.django-rest-framework.org/api-guide/serializers/#overriding-serialization-and-deserialization-behavior

答案 2 :(得分:0)

我找到了解决方法。

username = serializers.CharField(
    validators=[
        UniqueValidator(
            queryset=Account.objects.all(),
            message=convert_dictionary_to_json_string({
                'error_code': ErrorCode.parameter.value,
                'msg': 'username exists',
            }),
        ),
    ],
    # ...other validators
)

由于我们只能传递一个字符串类型的消息,在验证器中,我们可以:

  1. 构建一个包含我们需要的错误消息的字典
  2. 将此词典转换为JSON字符串
  3. 只需将JSON字符串传递给message字段
  4. 即可

    之后,在view代码中,如果验证失败:

    1. 我们将serializer.errors中的错误消息(即JSON字符串)转换为字典
    2. 将其打包至回复