Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django Rest框架对验证失败的自定义响应 背景_Python_Django_Validation_Django Rest Framework - Fatal编程技术网

Python Django Rest框架对验证失败的自定义响应 背景

Python Django Rest框架对验证失败的自定义响应 背景,python,django,validation,django-rest-framework,Python,Django,Validation,Django Rest Framework,我不熟悉Django和rest框架,我正在尝试使用Django rest框架为移动应用程序构建注册和登录的API演示 我想要 我使用的是APIView和ModelSerializer,用于注册的参数和约束是 email <required, unique>, username <required, unique>, password <required, unique>, 这将导致required验证失败,JSON响应将返回如下内容 "username":

我不熟悉Django和rest框架,我正在尝试使用Django rest框架为移动应用程序构建注册和登录的API演示

我想要 我使用的是
APIView
ModelSerializer
,用于注册的参数和约束是

email <required, unique>,
username <required, unique>,
password <required, unique>,
这将导致
required
验证失败,JSON响应将返回如下内容

"username": [
    "This field may not be blank."
]
{
    error_code: 1,
    msg: "blah blah blah"
}
但是,我希望JSON响应类似于

"username": [
    "This field may not be blank."
]
{
    error_code: 1,
    msg: "blah blah blah"
}
通过这种方式,移动应用程序可以根据错误代码做任何它想做的事情

问题 我发现,在框架的验证实现中,验证失败(所有字段验证失败)已转换为纯文本并打包在一个数组中,我无法获得特定的异常(如用户名要求的异常),并且我无法在响应中生成错误代码

那么,有什么方法可以捕获特定的异常吗?

您可以使用

代码 你可以用

代码
在序列化程序的
到_internal_value
中,可以捕获ValidationErrors并对其进行修改

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

在序列化程序的
到内部值中,可以捕获ValidationError并修改它们

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

我找到了一个解决办法

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
)
由于我们只能传递字符串类型的消息,因此在验证器中,我们可以:

  • 建立一个包含我们需要的错误信息的字典
  • 将此字典转换为JSON字符串
  • 只需将JSON字符串传递到
    消息
    字段
  • 之后,在
    视图中
    代码中,如果验证失败:

  • 我们将
    序列化程序中的错误消息(JSON字符串)转换为字典
  • 把它打包到响应中

  • 我找到了一个解决办法

    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
    )
    
    由于我们只能传递字符串类型的消息,因此在验证器中,我们可以:

  • 建立一个包含我们需要的错误信息的字典
  • 将此字典转换为JSON字符串
  • 只需将JSON字符串传递到
    消息
    字段
  • 之后,在
    视图中
    代码中,如果验证失败:

  • 我们将
    序列化程序中的错误消息(JSON字符串)转换为字典
  • 把它打包到响应中

  • 在响应中包含这些错误代码有什么具体原因吗?为什么客户端不能使用http错误代码?@mikedanylov http错误代码会有所帮助,但我希望错误更具体一些,例如
    必需的
    验证失败或
    唯一的
    验证失败。默认的http错误代码400似乎只是告诉我一些验证失败,这并不是特定的。那么您可能需要为所有字段编写自定义验证。可以通过为每个字段重写序列化程序的验证方法来完成。例如,对于密码,您需要覆盖方法
    validate\u password
    ,然后您可以按照自己的喜好格式化字段错误对象。在响应中包含这些错误代码有什么具体原因吗?为什么客户端不能使用http错误代码?@mikedanylov http错误代码会有所帮助,但我希望错误更具体一些,例如
    必需的
    验证失败或
    唯一的
    验证失败。默认的http错误代码400似乎只是告诉我一些验证失败,这并不是特定的。那么您可能需要为所有字段编写自定义验证。可以通过为每个字段重写序列化程序的验证方法来完成。例如,对于密码,您需要重写方法
    validate\u password
    ,在那里您可以随意设置字段错误对象的格式。谢谢,但我发现识别所需故障或唯一故障的线索是纯文本。是否有标志可以告诉我所需的故障或唯一的故障?纯文本包含在
    ValidationError.detail
    属性中,该属性应该是字典或列表。您可以阅读源代码以准确了解如何访问所需的数据。谢谢,但我发现识别所需故障或唯一故障的线索是纯文本。是否有标志可以告诉我所需的故障或唯一的故障?纯文本包含在
    ValidationError.detail
    属性中,该属性应该是字典或列表。您可以阅读源代码以准确了解如何访问所需的数据。谢谢,还有什么我要做的吗?在我添加代码后,它不起作用。谢谢,但是还有什么我应该做的吗?在我添加代码后,它就不起作用了。