Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.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 序列化可选嵌套结构:QueryDict和普通dict之间的区别?_Python_Django_Django Rest Framework - Fatal编程技术网

Python 序列化可选嵌套结构:QueryDict和普通dict之间的区别?

Python 序列化可选嵌套结构:QueryDict和普通dict之间的区别?,python,django,django-rest-framework,Python,Django,Django Rest Framework,在使用django rest编写嵌套结构,然后尝试使用django rest的测试客户端测试它们时,我遇到了奇怪的行为。嵌套的子对象应该是可选的 下面是一个示例序列化程序: from rest_framework import serializers class OptionalChildSerializer(serializers.Serializer): field_b = serializers.IntegerField() field_c = serializers.I

在使用django rest编写嵌套结构,然后尝试使用django rest的测试客户端测试它们时,我遇到了奇怪的行为。嵌套的子对象应该是可选的

下面是一个示例序列化程序:

from rest_framework import serializers

class OptionalChildSerializer(serializers.Serializer):
    field_b = serializers.IntegerField()
    field_c = serializers.IntegerField()

    class Meta:
        fields = ('field_b', 'field_c', )

class ParentSerializer(serializers.Serializer):
    field_a = serializers.IntegerField()
    child = OptionalChildSerializer(required=False, many=False)

    class Meta:
        fields = ('a', 'child',)

    def perform_create(self, serializer):
        # TODO: create nested object.
        pass
我省略了perform_create中的代码,因为它与问题无关

现在,将普通dict作为数据参数传递就可以了:

ser = ParentSerializer(data=dict(field_a=3))
ser.is_valid(raise_exception=True)
但通过QueryDict将失败:

from django.http import QueryDict
ser = ParentSerializer(data=QueryDict("field_a=3"))
ser.is_valid(raise_exception=True)

ValidationError: {'child': {'field_b': [u'This field is required.'], 'field_c': [u'This field is required.']}}
在实际的web站点上,API获得了正常的dict,因此工作正常。但是,在测试过程中,使用client.post'url',data=dictfield_a=3将导致QueryDict被传递到视图,因此不起作用


所以我的问题是:疑问词和普通词有什么区别?还是我的方法不对?

django rest测试客户端不会自动将数据序列化为json,而是使用多部分/表单,这会导致查询

然而,这里描述了一个格式选项。以下测试代码工作正常:

client.post('url', format='json', data=dict(field_a=3))
我仍然对普通dict和QueryDict之间不同的序列化程序行为感到困惑,尽管


谢谢Rajesh为我指明了正确的方向

django rest测试客户端不会自动将数据序列化为json,而是使用multipart/form,这会导致查询

然而,这里描述了一个格式选项。以下测试代码工作正常:

client.post('url', format='json', data=dict(field_a=3))
我仍然对普通dict和QueryDict之间不同的序列化程序行为感到困惑,尽管

谢谢Rajesh为我指明了正确的方向

DRF定义了多个解析器类,用于解析具有不同媒体类型的请求内容

根据用于解析请求内容的解析器,request.data通常是QueryDict或普通字典

JSONParser: 它解析JSON请求内容,即.media_类型为application/JSON的内容

表单分析器 它解析HTML表单内容。在这里,request.data由一组查询数据填充。它们的.media_类型为application/x-www-form-urlencoded

多部件分析器 它解析多部分HTML表单内容,支持文件上传。这里,两个request.data都用QueryDict填充。这些有 .media_类型为多部分/表单数据

文件上传解析器 它解析原始文件上载内容。request.data属性是一个字典,其中包含一个包含上载文件的密钥文件

DRF如何定义解析器

当DRF访问request.data时,它检查传入请求的内容类型头,然后确定使用哪个解析器来解析请求内容

发送数据时,您需要设置内容类型标头,否则它将使用多部分或表单解析器来解析请求内容,并在request.data中为您提供QueryDict,而不是字典

根据DRF文件

如果不设置内容类型,大多数客户端将默认使用 “application/x-www-form-urlencoded”,这可能不是您想要的

因此,在发送json编码的数据时,还要将内容类型头设置为application/json,然后它将按预期工作

为什么request.data有时是QueryDict,有时是dict

这是因为不同的编码具有不同的数据结构和属性

例如,表单数据是一种支持相同值的多个键的编码,而json不支持这种编码

同样对于JSON数据,request.data可能根本不是dict,它可以是一个列表或任何其他JSON原语

看看这个差不多

你需要做什么

发布数据时,可以在测试中添加format='json',这将设置内容类型并正确序列化数据

client.post('url', format='json', data=dict(field_a=3))
您还可以使用content-type参数发送JSON编码的内容

client.post('url', json.dumps(dict(field_a=3)), content_type='application/json')
DRF定义了多个解析器类,用于解析具有不同媒体类型的请求内容

根据用于解析请求内容的解析器,request.data通常是QueryDict或普通字典

JSONParser: 它解析JSON请求内容,即.media_类型为application/JSON的内容

表单分析器 它解析HTML表单内容。在这里,request.data由一组查询数据填充。它们的.media_类型为application/x-www-form-urlencoded

多部件分析器 它解析多部分HTML表单内容,支持文件上传。这里,两个request.data都用QueryDict填充。这些有 .media_类型为多部分/表单数据

文件上传解析器 它解析原始文件上载内容。request.data属性是一个字典,其中包含一个包含上载文件的密钥文件

DRF如何定义解析器

当DRF访问request.data时,它检查传入请求的内容类型头,然后确定 使用哪个解析器来解析请求内容

发送数据时,您需要设置内容类型标头,否则它将使用多部分或表单解析器来解析请求内容,并在request.data中为您提供QueryDict,而不是字典

根据DRF文件

如果不设置内容类型,大多数客户端将默认使用 “application/x-www-form-urlencoded”,这可能不是您想要的

因此,在发送json编码的数据时,还要将内容类型头设置为application/json,然后它将按预期工作

为什么request.data有时是QueryDict,有时是dict

这是因为不同的编码具有不同的数据结构和属性

例如,表单数据是一种支持相同值的多个键的编码,而json不支持这种编码

同样对于JSON数据,request.data可能根本不是dict,它可以是一个列表或任何其他JSON原语

看看这个差不多

你需要做什么

发布数据时,可以在测试中添加format='json',这将设置内容类型并正确序列化数据

client.post('url', format='json', data=dict(field_a=3))
您还可以使用content-type参数发送JSON编码的内容

client.post('url', json.dumps(dict(field_a=3)), content_type='application/json')

在data=QueryDictfield_a=3中,是否应引用字段_a=3?在data=dictfield\u a=3测试用例代码中没有引用它。请求中的“内容类型”是什么?啊,我还没有设置它,但我想这会使它成为多部分/形式。我期待django rest自动提供application/json。这当然是我的查询信息的来源。在data=QueryDictfield\u a=3中,应该引用field\u a=3吗?在data=dictfield\u a=3测试用例代码中没有引用它。请求中的“内容类型”是什么?啊,我还没有设置它,但我想这会使它成为多部分/形式。我期待django rest自动提供application/json。这当然是我的疑问的来源。谢谢你详细的回答,解决了我的问题。为了进一步参考,您可以添加在测试中添加format='json'设置内容类型以及正确序列化数据。感谢详细的回答,解决了我的问题。为了进一步参考,您可以添加在测试中添加format='json'设置内容类型以及正确序列化数据。