【问题标题】:Advanced Webapp2 Routing高级 Webapp2 路由
【发布时间】:2012-01-11 18:08:23
【问题描述】:

在老式 webapp 中,基于 app.yaml 的路由允许您检查正则表达式,如果匹配,则由名称基于找到的模式的处理程序处理请求。例如,如果匹配的模式是“用户”,\1_handler.py 将分派给 user_handler.py。

有没有办法用 webapp2.Route 做同样的事情?惰性处理程序或method_handler参数是否可以基于模板中的匹配模式?

【问题讨论】:

  • 您在这里谈论的是两个不同的东西 - app.yaml 和您的 Web 框架。您仍然可以在 webapp2 中使用基于 app.yaml 的路由。
  • 是的,我知道。但我想要做的是根据 URL 的内容,让请求处理程序类中的不同方法处理请求。因此,如果是用户/显示,我希望它转到 Handler:show,如果是用户/添加,我希望它转到用户:添加。我正在为三种类型的实体(用户+2)和 5 种类型的操作执行此操作。您可以在 15 条路线 ineebapp2 中执行此操作。但我正在研究如何将其缩小到 3 或 1。我看不出 app.yaml 定义如何允许我定义方法。
  • 不会,但这不是您在原始问题中要问的。实际上,我不确定它是如何关联的。
  • "lazy handler或者method_handler参数可以基于template中匹配的模式吗?"
  • 您似乎在谈论根据路径路由到模块,而不是选择方法。无论如何,您尝试做的事情并不真正符合 webapp2 的 RESTful 精神,后者将每个不同的函数都由不同的处理程序类处理。

标签: google-app-engine webapp2


【解决方案1】:

webapp2 不允许这样路由。我认为最合理的解决方案是为webapp2.Router编写一个自定义调度程序。

可以像这样设置自定义调度程序:

app = WSGIApplication(...)
app.router.set_dispatcher(custom_dispatcher)

这是一个未测试的草图,用于调度程序,代码基于webapp2.Router.default_dispatcher

from webapp2 import import_string

def custom_dispatcher(router, request, response):
    route, args, kwargs = rv = router.match(request)
    request.route, request.route_args, request.route_kwargs = rv

    handler = route.handler
    if isinstance(handler, basestring):

        handler, args, kwargs = _parse_handler_template(handler, args, kwargs)

        if handler not in self.handlers:
            router.handlers[handler] = handler = import_string(handler)
        else:
            handler = router.handlers[handler]

    return router.adapt(handler)(request, response)

def _parse_handler_template(handler, args, kwargs):
    """replace {key} in `handler` with values from `args` or `kwargs`.
    Replaced values are removed from args/kwargs."""
    args = list(args)
    kwargs = dict(kwargs)
    def sub(match):
        if kwargs:
            return kwargs.pop(match.group().strip('{}'))
        else:
            return args.pop(int(match.group().strip('{}'))
    return re.sub('{.*?}', sub, handler), args, kwargs

此代码应该允许注册这样的规则:

 app = WSGIApplication([
     (r'module/<module>/<action>/<argument>', 'modules.{module}.action_{action}'),
 ])

此示例不允许在方法名称中使用模式中的变量,例如:module.Class:action_{method}。在Route 类中,此端点由分号分隔,值存储在route.method_nameroute.handler 中。

【讨论】:

    猜你喜欢
    • 2018-01-12
    • 2012-01-17
    • 1970-01-01
    • 2010-12-23
    • 2014-10-28
    • 2011-09-02
    • 2018-06-26
    • 1970-01-01
    相关资源
    最近更新 更多