Since Django 1.5 raw post data is accessible via 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
答案 0 :(得分:23)
如果(1)该请求方法是POST,则会在请求时触发错误You cannot access body after reading from request's data stream
,(2)在中间件中访问请求的POST字典,process_request
或{{1} }和(3)在视图函数中,访问process_view
。 (3)即使错误的真正原因是(2),也会引发错误。
为了解决错误,您需要检查中间件访问的位置request.body
并修改它,使其不再访问request.POST
。
Django文档说middleware should not access request.POST
,这是忽略该推荐的一个结果。
另请查看this Django ticket on the issue,其中包括注释:
[M]击中request.POST的软件应该(通常)被视为a 错误。这意味着该视图将无法设置任何自定义上传 处理程序,执行请求正文的自定义解析或强制执行 在接受文件上传之前进行权限检查。
答案 1 :(得分:7)
在Adam Easterling的回答中,值得注意的是Django本身' violates'在中间件中使用request.POST 不的提示:
CsrfViewMiddleware类可以被视为异常 提供允许的csrf_exempt()和csrf_protect()装饰器 视图以明确控制CSRF验证应在何时进行 发生。
哪些不会违反IMO的违规行为
答案 2 :(得分:1)
使用request.data
代替request.body
。
request.data
不会再次读取数据流。
答案 3 :(得分:1)
对于那些有兴趣的人,我遇到了这个问题-从请求的数据流中读取后您无法访问正文-当我添加 'oauth2_provider.contrib.rest_framework.OAuth2Authentication' 在“ REST_FRAMEWORK”中,就像在settings.py-
中一样REST_FRAMEWORK = { ... 'DEFAULT_AUTHENTICATION_CLASSES':( ... 'oauth2_provider.contrib.rest_framework.OAuth2Authentication', ... ),
当然,禁用此功能将起作用,但我无法为此而解决。
答案 4 :(得分:0)
在将@csrf_exempt放到我的视图功能之前,我能够读取我的request.POST。因为CSRF中间件访问POST数据。
答案 5 :(得分:0)
对于那些没有准备好正文或POST的具有相同错误的人,当我在process_view中间件中使用以下代码行时,我也遇到了相同的错误:
event = request.event if 'event' in request else None
已通过设置request.event =解决,此功能位于顶部,因此我可以使用:
event = request.event