问题 Django Rest Framework:空的request.data


我有以下代码来查看DRF:

from rest_framework import viewsets

class MyViewSet(viewsets.ViewSet):

    def update(self, request, pk = None):
        print pk
        print request.data

我通过URL调用URL 蟒蛇,请求 以下列方式:

import requests
payload = {"foo":"bar"}
headers = {'Content-type': 'application/json'}
r = requests.put("https://.../myPk", data= payload, headers=headers)

但是当从服务器收到请求时,request.data为空。这里有输出:

myPk
<QueryDict: {}>

我该如何解决这个问题?


8375
2018-06-05 16:50


起源

尝试使用requests.post - Mikeec3
Mikeec3休息框架的文件说: request.data返回请求正文的已解析内容。这类似于标准的request.POST和request.FILES属性,除了: - 它包括所有已解析的内容,包括文件和非文件输入。 - 它支持解析除POST之外的HTTP方法的内容,这意味着您可以访问PUT和PATCH请求的内容。  - 它支持REST框架的灵活请求解析,而不仅仅是支持表单数据。例如,您可以像处理传入表单数据一样处理传入的JSON数据。 - floatingpurr


答案:


你需要发送 payload 作为序列化 json 目的。

import json
import requests
payload = {"foo":"bar"}
headers = {'Content-type': 'application/json'}
r = requests.put("https://.../myPk/", data=json.dumps(payload), headers=headers)

否则会发生什么事情,DRF实际上会抱怨:

*** ParseError: JSON parse error - No JSON object could be decoded

您将通过调试视图看到该错误消息(例如,使用 PDB 要么 IPDB)或打印变量,如下所示:

def update(self, request, pk = None):
    print pk
    print str(request.data)

12
2018-06-05 18:09



我试图将字典序列化为json,但它仍然无效。当我读取var值的打印时,我总是得到 myPk 和 <QueryDict: {}>。 - floatingpurr
你做什么输出你得到什么 print request.stream.read() 代替 print request.data (删除很重要 print request.data 对于那个测试)。这应该显示您的请求中未更改的原始数据。你看到了什么吗? .stream中的文档 - sthzg
我添加了这条线 print request.stream.read() 之后立马 def update(self, request, pk = None):。输出是: AttributeError: 'NoneType' object has no attribute 'read' - floatingpurr
好的,我解决了!问题是:(i)JSON序列化和(ii)请求URL中的斜杠。 r = requests.put("https://.../myPk/", data=json.dumps(payload), headers=headers)。 sthzg,如果你更新上面的答案的URL,添加一个尾随的slashi,我可以将其标记为已接受(希望它是stackexchange的常规操作...) - floatingpurr
很高兴你解决了它。我实际上考虑了尾部斜杠并在测试代码中使用它,但是没有它就忘了测试它的错误。更新了答案中的路径。 - sthzg


在这里查看2个问题: -

  1. Json格式是否合适。
  2. 网址是否正确(我在网址中缺少尾随反斜杠,因为我正面临这个问题)

希望能帮助到你


3
2018-03-31 19:05





假设您需要执行足够新的请求:

import requests

payload = {"foo":"bar"}
r = requests.put("https://.../myPk", json=payload, headers=headers)

然后它将为您正确格式化有效负载并提供适当的标头。否则,你正在发送 application/x-www-urlformencoded DRF无法正确解析的数据,因为您告诉它您正在发送JSON。


1
2018-06-06 16:48



好的,但是我指定了格式 headers = {'Content-type': 'application/json'} - floatingpurr