例外:从请求的数据流中读取后,您无法访问正文

kev*_*kev 25 django post exception request

由于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
Run Code Online (Sandbox Code Playgroud)

Ada*_*ing 30

该错误You cannot access body after reading from request's data stream将在请求被触发,如果(1),该请求的方法是POST,(2),该请求的POST字典在中间件访问,在任一process_requestprocess_view和(3)的视图函数中,request.body被访问.在(3)上,即使错误的真正原因是(2),也会引发错误.

为了解决该错误,您需要检查中间件的访问位置request.POST并对其进行修改,使其不再访问request.POST.

Django文档说中间件不应该访问request.POST,这是忽略该建议的一个结果.

另请查看此问题的Django票证,其中包括注释:

[M]命中请求的谜语.POST应该(通常)被认为是一个错误.这意味着视图将无法设置任何自定义上载处理程序,执行请求正文的自定义解析,或在接受文件上载之前强制执行权限检查.

  • 应该补充一点,这不仅适用于`request.POST`,还适用于`request.body`. (12认同)
  • 我实际上需要访问 request.data 我该怎么做? (2认同)

Rom*_*eno 7

添加到Adam Easterling的答案值得注意的是,Django本身" 违反了 " 在中间件中使用request.POST 的暗示:

CsrfViewMiddleware类可以被视为异常,因为它提供了csrf_exempt()和csrf_protect()装饰器,这些装饰器允许视图显式控制CSRF验证应在何时发生.

哪个没有消毒IMO的违规行为

  • 事实上,这对我来说是一种烦恼.解决方案/解决方法是使用PUT而不是POST,如果您的意思是读取请求正文(除了通过POST/FILES). (2认同)

小智 5

使用request.data代替request.body

request.data 不会再次读取数据流。

  • 这是修复错误的实际答案。应该有更高的赞成票。 (5认同)
  • 我在 Django 1.4 中使用“request.data”得到“AttributeError: 'WSGIRequest' object has no attribute 'data'”。关于如何解决这个问题的一些想法? (3认同)
  • @CarMoreno @Ulvi 我相信 `request.data` 是一个 DRF 的东西。传递到 DRF 视图的“request”对象与传递到普通 django 视图的“request”对象不同。 (3认同)