質問

このミドルウェアを使用してアプリを休ませていますが、フォームパラメータが届いていないようです。

from google.appengine.ext import webapp

class RestHTTPMiddleware(object):
  def __init__(self, app):
    self.app = app

  def __call__(self, environ, start_response):
    method = webapp.Request(environ).get('_method')
    request = Request(environ)
    environ['wsgi.input'] = StringIO.StringIO(request.body)

    if method:
      environ['REQUEST_METHOD'] = method.upper()

    return self.app(environ, start_response)

フォームを送信し、次を使用してデバッグするとき:

def put(self):
    logging.debug(self.request.get('description'))

ロガーは空です。put(self) メソッドが呼び出されています。ロガーを使用してテストしたところ、デバッグ メッセージが表示されました。

2 回目の改訂:

from google.appengine.ext import webapp
from webob import Request
import logging
import StringIO

class RestHTTPMiddleware(object):
  def __init__(self, app):
    self.app = app

  def __call__(self, environ, start_response):
    request = Request(environ)
    environ['wsgi.input'] = StringIO.StringIO(request.body)

    method = webapp.Request(environ).get('_method')

    if method:
      environ['REQUEST_METHOD'] = method.upper()

    return self.app(environ, start_response)

最新の変更点:

from google.appengine.ext import webapp
from webob import Request
import logging
import StringIO

class RestHTTPMiddleware(object):
  def __init__(self, app):
    self.app = app

  def __call__(self, environ, start_response):
    request = Request(environ)
    body = StringIO.StringIO(request.body)

    method = webapp.Request(environ).get('_method', None)

    if method:
      environ['REQUEST_METHOD'] = method.upper()
      environ['wsgi.input'] = body

    return self.app(environ, start_response)
役に立ちましたか?

解決

webapp.Request をインスタンス化し、その上で .get を呼び出すと、リクエストの本文が読み取られ、その中のフォーム パラメーターが解析されます。実際の Web アプリが後で開始されると、別のリクエスト オブジェクトがインスタンス化され、再度リクエスト本文の読み取りが試行されますが、すでに読み取られているため、何も返されません。

ミドルウェアを変更してリクエスト本文のコピーを保存し、それを WSGI 環境に戻すことができます。他にも次のようなオプションがあります。

  • _method 引数が投稿されたフォーム パラメーターではなく常にクエリ文字列パラメーターになる場合は、リクエスト本文を読み取らない webapp.Request(environ).GET.get('method') を使用できます。
  • オーバーライドすることもできます WSGIアプリケーション。電話 ディスパッチ方法を変更します。
  • WSGIApplication をサブクラス化し、カスタムの リクエスト_クラス, は、実際のリクエスト オブジェクトを構築し、渡された環境をユーザーに合わせて変更する関数です (ハック!)。
  • initialize() を実装するカスタム Web アプリの RequestHandler 基本クラスを定義し、リクエスト オブジェクトの WSGI dict にアクセスしてメソッドを変更することができます (ハック!)。
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top