由于 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
使用 request.data
而不是 request.body
。
request.data
不会再次读取数据流。
的 POST 字典在中间件中访问,process_request
或process_view
中访问,以及 (3) 在视图函数中访问request.body
,则会在请求时触发错误You cannot access body after reading from request's data stream
。在 (3) 上将引发错误,即使错误的真正原因是 (2)。
为了解决此错误,您需要检查中间件的访问位置request.POST
并对其进行修改,使其不再访问request.POST
。
Django 文档说中间件不应该访问request.POST
,这是忽略该建议的一个结果。
另请查看关于这个问题的 Django 票证,其中包括以下注释:
[M]点击请求的空闲软件。开机自检应(通常)被视为 错误。这意味着视图将无法设置任何自定义上传 处理程序,执行请求正文的自定义分析,或强制执行 在接受文件上传之前进行权限检查。
除了Adam Easterling的回答之外,值得注意的是,Django本身"违反了"不使用request的暗示。中间件中的开机自检:
CsrfViewMiddleware类可以被认为是一个例外,因为它 提供 csrf_exempt() 和 csrf_protect() 装饰器,允许 用于显式控制 CSRF 验证应在什么点进行视图 发生。
这并不能消除IMO的违规行为
对于那些有兴趣知道的人,我遇到了这个问题:
从请求的数据流读取后无法访问正文
当我添加'oauth2_provider.contrib.rest_framework时。OAuth2Authentication'在"REST_FRAMEWORK"中,就像在 settings.py 中这样:
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
...
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
...
),
当然,禁用此功能将起作用,但不是我会引以为豪的解决方法。
我能够阅读我的请求。将@csrf_exempt放在我的视图功能之前后开机自检。因为 CSRF 中间件访问 POST 数据。
对于那些没有准备好正文或 POST 的相同错误的人,当我在process_view中间件中使用这行代码时,我遇到了同样的错误:
event = request.event if 'event' in request else None
通过函数顶部的设置解决 request.event = 无,所以我可以使用:
event = request.event
我找到了一个技巧,用于我的中间件,
request._read_started = False
完成此操作后,再次准备好身体,它可以工作。