Django Rest Framework: empty request.data
对于DRF,我有以下代码:
1 2 3 4 5 6 7
| from rest_framework import viewsets
class MyViewSet(viewsets.ViewSet):
def update(self, request, pk = None):
print pk
print request.data |
我以以下方式通过python-requests调用URL:
1 2 3 4
| import requests
payload = {"foo":"bar"}
headers = {'Content-type': 'application/json'}
r = requests.put("https://.../myPk", data= payload, headers=headers) |
但是从服务器接收到请求时,request.data为空。这里是输出:
如何解决此问题?
- 尝试使用request.post
-
Mikeec3其余框架的文档说:request.data返回请求正文的解析内容。这类似于标准的request.POST和request.FILES属性,除了:-它包括所有已解析的内容,包括文件和非文件输入。 -它支持解析POST以外的HTTP方法的内容,这意味着您可以访问PUT和PATCH请求的内容。 -它支持REST框架的灵活请求解析,而不仅仅是支持表单数据。例如,您可以以处理传入表单数据的相同方式处理传入JSON数据。
-
我遇到了同样的问题,但是仅当我使用自定义解析器时,即使解析器是1-1的默认解析器,将相同的单词逐字复制并粘贴到新模块中,也会出现相同的问题。它仅在使用json主体时发生,而不是在UI中的表单数据时发生。我可以看到数据以request.body的形式出现,但不是request.data。如果删除我的自定义解析器,则将其恢复为一般的request.body和request.data。我的stream.read()看起来完全一样,只是request.body被填充,而request.data没有。
-
这个问题可能重复
您需要将payload作为序列化的json对象发送。
1 2 3 4 5
| import json
import requests
payload = {"foo":"bar"}
headers = {'Content-type': 'application/json'}
r = requests.put("https://.../myPk/", data=json.dumps(payload), headers=headers) |
否则,DRF实际上会抱怨:
1
| *** ParseError: JSON parse error - No JSON object could be decoded |
您可以通过调试视图(例如使用pdb或ipdb)或打印如下变量来查看该错误消息:
1 2 3
| def update(self, request, pk = None):
print pk
print str(request.data) |
- 我试图将字典序列化为json,但仍然无法正常工作。当我读取var值的打印内容时,总是得到myPk和<QueryDict: {}>。
-
当您执行print request.stream.read()而不是print request.data时会得到什么输出(对于该测试,删除print request.data很重要)。这应该显示您请求中未更改的原始数据。你在那里看到什么吗?文档中的.stream
-
我在def update(self, request, pk = None):之后立即添加了print request.stream.read()行。输出为:AttributeError: 'NoneType' object has no attribute 'read'
-
好吧,我解决了!问题是:(i)JSON序列化和(ii)请求URL中的尾部斜杠。 r = requests.put("https://.../myPk/", data=json.dumps(payload), headers=headers)。 sthzg,如果您更新答案上方的yout的URL,添加结尾的slashi,我可以将其标记为已接受(希望它是stackexchange的常规操作...)
-
很高兴您解决了问题。我实际上想到了斜杠并在测试代码中使用了它,但是却忘记了在没有斜杠的情况下对其进行测试。更新了答案中的路径。
在此处检查2个问题:-
Json格式是否正确。
网址正确与否(由于遇到问题,我在网址中缺少尾部反斜杠)
希望对您有所帮助
假设您正在使用足够新版本的请求,请执行以下操作:
1 2 3 4
| import requests
payload = {"foo":"bar"}
r = requests.put("https://.../myPk", json=payload, headers=headers) |
然后它将为您正确格式化有效负载并提供适当的标头。否则,您将发送DRF无法正确解析的application/x-www-urlformencoded数据,因为您告诉它您正在发送JSON。
-
好的,但是我在headers = {'Content-type': 'application/json'}中指定了格式