当我用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\u create中的代码,因为它与问题无关)。在
现在,传递一个普通的dict作为数据参数就可以了:
^{pr2}$但是,传递一个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=dict(field_a=3))
之类的东西将导致一个QueryDict被传递到视图,因此无法工作。在
所以我的问题是:QueryDict和普通dict有什么区别?还是我走错了路?在
django rest测试客户机不会自动将数据序列化为json,而是使用multipart/form,这将导致QueryDict。在
但是,有一个格式选项,描述为in the docs。以下测试代码工作正常:
我仍然对普通dict和QueryDict之间不同的序列化程序行为感到困惑,尽管。。。在
谢谢拉杰什给我指出了正确的方向!在
DRF定义了多个解析器类,用于解析具有不同媒体类型的请求内容。
request.data
通常是QueryDict
或普通字典,这取决于用于解析请求内容的解析器。在它解析JSON请求内容,即带有
.media_type
的内容为application/json
。在它解析HTML表单内容。在这里,
request.data
填充了QueryDict
的数据。这些数据的.media_type
为application/x-www-form-urlencoded
。在它解析支持文件上传的多部分HTML表单内容。这里,两个
request.data
都填充了QueryDict
。这些有.media_type
作为multipart/form-data
。在它解析原始文件上载内容。
request.data
属性是一个包含上载文件的单键file
的字典。在DRF determines如何解析?
当DRF访问
request.data
时,它检查传入请求的Content-Type
报头,然后确定使用哪个解析器来解析请求内容。在在发送数据时,您需要设置
Content-Type
头,否则它将使用多部分或表单解析器解析请求内容,并在request.data
中给您一个QueryDict
,而不是字典。在根据DRF文件
^{bq}$因此,在发送json编码的数据时,还应将
Content-Type
头设置为application/json
,然后它将按预期工作。在为什么请求数据有时是}?
QueryDict
,有时是{这样做是因为不同的编码具有不同的数据结构和属性。
例如,表单数据是一种编码,它支持相同值的多个键,而json不支持这一点。在
同样,对于JSON数据,
request.DATA
可能根本不是dict
,它可以是一个列表或任何其他JSON原语。在看看这个Google Groups thread差不多。在
你需要做什么?
您可以在测试中添加
format='json'
,当POSTing
的数据将设置内容类型并正确序列化数据。在还可以使用
^{pr2}$content-type
参数发送JSON编码的内容。在相关问题 更多 >
编程相关推荐