因为Django 1.5的原始发布数据可以通过request.body访问。
在我的应用程序中,我有时会通过一个表单接收数据,有时会接收原始数据(例如json)。有没有什么方法可以编写这样一个不会失败的函数?
def get_post_var(request, name):
result = request.POST.get(name)
if result:
return result
post_body = dict(urlparse.parse_qsl(request.body))
result = post_body.get(name)
if result:
return result
return None
7条答案
按热度按时间pinkon5k1#
使用
request.data
而不是request.body
。request.data
不再读取数据流。zrfyljdw2#
如果(1)请求方法是POST,(2)在中间件中访问请求的POST字典,在
process_request
或process_view
中,以及(3)在视图函数中访问request.body
,则会在请求上触发错误You cannot access body after reading from request's data stream
。即使错误的真实的原因是(2),也会在(3)上引发错误。为了解决这个错误,您需要检查中间件在哪里访问
request.POST
,并修改它,使它不再访问request.POST
。Django的文档说middleware should not access
request.POST
,这是忽略这个建议的一个后果。还可以查看this Django ticket on the issue,其中包括以下注解:
命中请求的[M]iddleware。POST(通常)应视为Bug。这意味着视图将无法设置任何自定义上载处理程序,执行请求正文的自定义语法分析,或在接受文件上载之前强制执行权限检查。
qyuhtwio3#
除了Adam Easterling的回答之外,值得注意的是Django本身“违反了”不使用中间件中的request.POST的提示:
可以将CsrfViewMiddleware类视为一个例外,因为它提供了csrf_exempt()和csrf_protect()装饰器,允许视图显式控制CSRF验证应该在什么时候进行。
这并不能消除违反IMO的行为
zy1mlcev4#
对于那些有兴趣知道,我面临这个问题:
阅读请求的数据流后无法访问正文
当我oauth2_provider.contrib.rest在“REST_FRAMEWORK”中添加“www.example.com_framework.OAuth2Authentication”时,就像在www.example.com中一样settings.py:
当然,禁用这将工作,但不是一个变通办法,我会感到自豪。
jmp7cifd5#
在我的视图函数前放置@csrf_exempt后,我能够读取我的请求。POST。因为CSRF中间件访问POST数据。
ajsxfq5m6#
我发现了一个窍门,用于我的中间件,
在这样做之后,再次准备身体,它就工作了。
ffdz8vbo7#
对于那些没有准备好主体或POST的人,当我在process_view中间件中使用这行代码时,我也遇到了同样的错误:
通过设置请求解决。函数顶部的event = None,这样我就可以用途: