web-dev-qa-db-ja.com

例外:リクエストのデータストリームから読み取った後、本文にアクセスできません

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
26
kev

エラーYou cannot access body after reading from request's data streamは、(1)リクエストメソッドがPOSTである場合、(2)リクエストのPOST辞書がミドルウェアでアクセスされている場合、process_requestまたはprocess_viewおよび(3)ビュー関数内でrequest.bodyにアクセスします。バグの本当の原因は(2)ですが、(3)でエラーが発生します。

エラーを解決するには、ミドルウェアがrequest.POSTにアクセスする場所を調べ、request.POSTにアクセスしないように変更する必要があります。

Django docsは、 ミドルウェアがrequest.POST にアクセスするべきではないと言っています。これは、それを無視した結果の1つです勧告。

また、 this Djangoチケットに関する問題 )も確認してください。

[M] request.POSTにヒットするミドルウェアは(通常)バグと見なされます。これは、ビューがカスタムアップロードハンドラーを設定したり、リクエスト本文のカスタム解析を実行したり、ファイルアップロードが受け入れられる前に権限チェックを実施したりできないことを意味します。

26
Adam Easterling

Adam Easterlingの回答に加えて、Django自体 ' violates 'のヒントがnotリクエストを使用していることに注意してください。ミドルウェアでのPOST:

CsrfViewMiddlewareクラスはcsrf_exempt()およびcsrf_protect()デコレータを提供するため、例外と見なすことができます。これにより、ビューがCSRF検証を実行するポイントを明示的に制御できます。

違反IMOを無害化しないもの

7
Romeno

使用する request.data の代わりに request.body

request.dataはデータストリームを再度読み取りません。

3
Arnab Biswas

ビュー関数の前に@csrf_exemptを置いた後、request.POSTを読み取ることができました。 CSRFミドルウェアがPOSTデータにアクセスするためです。

0
Sia

BodyまたはPOSTの準備ができていない同じエラーが発生する場合は、process_viewミドルウェアで次のコード行を使用したときに、同じエラーが発生しました。

   event = request.event if 'event' in request else None

設定request.event =なしで関数の上部に解決されたので、次のように使用できます。

    event = request.event
0
PhoebeB