我如何将额外的参数传递给 dispatch()?

How do I pass additional params to dispatch()?

我写的 API 通过 URL 接受两个参数 - 例如 /api/targets/foo/bar

app = webapp2.WSGIApplication([
    ('/api/targets/(\w*?)/(\w*?)$', MainPage),
], debug=True)

这将触发 GET 处理程序:

def get(self, url_1, url_2):
    #do some stuff

这里很酷的是我可以在我的 GET 处理程序中引用 url_1 (foo) 和 url_2 (bar),它们是为我定义的。

我有另一个页面接受 GET 和 POST 请求。在这两种情况下,大约 90% 的情况都是相同的,因此我选择使用 def dispatch() 而不是使用两个单独的处理程序。

这里的问题是(即使我的 webapp2.WSGIApplication 初始化中仍然包含正则表达式块)它们不再传递给请求处理程序,所以我必须这样定义它们:

    url_1= self.request.url.split("/")[3]
    url_2= self.request.url.split("/")[4]

这让我觉得自己像个苦工。如果我告诉 dispatch() 期望这两个参数,它们永远不会到达——我需要做什么来模仿 dispatch 中的 get 行为?

使用起来会更短:

arg_one = self.request.route_args[0]
arg_two = self.request.route_args[1]

查看请求对象的 webapp2 docs,特别是请求部分底部的 route_argsroute_kwargs

这是一个有趣的用例。如果我是你,我会将 get() 和 post() 分开。如果 get() 和 post() 共享代码,那么我会将该代码移动到可以从 get() 和 post() 调用的 RequestHandler 方法中,或者移动共享代码进入另一个 class(我发现我的很多 RequestHandlers 只是在我的模型 classes 上调用方法)。

如果您仍然想要一种方法来替换 get() 和 post(),那么我建议您为 Route 设置 handler_method 而不是使用 dispatch()(参见 here in the docs).我建议不要完全在 dispatch() 方法中处理这些请求,因为它应该在某些时候调用 "handler method",默认为 GET/POST/etc。基于 HTTP 方法,但您可以设置自己的处理程序方法来处理 GET 和 POST 以及其他任何内容。

如果你设置 handler_method,它看起来像这样:

# note that handler_method is the method name as a string
app = webapp2.WSGIApplication([
    ('/api/targets/(\w*?)/(\w*?)$', MainPage, handler_method='handle_request'),
], debug=True)

在您的处理程序中:

class MainPage(webapp2.RequestHandler):
    # note that your method signature MUST have args for the route args,
    # or else an exception will occur
    def handle_request(self, arg_one, arg_two):
        # your code here
        if self.request.method == 'GET':
            # do GET stuff
        elif self.request.method == 'POST':
            # do POST stuff

这很好,因为它使 dispatch() 保持不变。我喜欢将 dispatch() 视为要发生 before/after 调用 get()/post()/您指定的任何处理程序方法的预处理和 post 处理。