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
エラー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にヒットするミドルウェアは(通常)バグと見なされます。これは、ビューがカスタムアップロードハンドラーを設定したり、リクエスト本文のカスタム解析を実行したり、ファイルアップロードが受け入れられる前に権限チェックを実施したりできないことを意味します。
Adam Easterlingの回答に加えて、Django自体 ' violates 'のヒントがnotリクエストを使用していることに注意してください。ミドルウェアでのPOST:
CsrfViewMiddlewareクラスはcsrf_exempt()およびcsrf_protect()デコレータを提供するため、例外と見なすことができます。これにより、ビューがCSRF検証を実行するポイントを明示的に制御できます。
違反IMOを無害化しないもの
使用する request.data
の代わりに request.body
。
request.data
はデータストリームを再度読み取りません。
ビュー関数の前に@csrf_exemptを置いた後、request.POSTを読み取ることができました。 CSRFミドルウェアがPOSTデータにアクセスするためです。
BodyまたはPOSTの準備ができていない同じエラーが発生する場合は、process_viewミドルウェアで次のコード行を使用したときに、同じエラーが発生しました。
event = request.event if 'event' in request else None
設定request.event =なしで関数の上部に解決されたので、次のように使用できます。
event = request.event