2012-01-11 84 views
1

在旧学校的webapp中,基于app.yaml的路由允许您检查正则表达式,如果匹配,则通过名称基于找到的模式的处理程序处理请求。例如,如果匹配的模式是'user',\ 1_handler.py将派发到user_handler.py。高级Webapp2路由

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

+1

你在谈论两个不同的东西 - app.yaml和你的web框架。您仍然可以在webapp2上使用基于app.yaml的路由。 – 2012-01-12 04:37:57

+0

是的,我知道。但是我想要做的是根据URL的内容在请求处理程序类中通过不同方法处理请求。因此,如果它是用户/节目,我希望它去处理程序:显示,如果它是用户/添加,我希望它去用户:添加。我正在为三种类型的实体(用户+2)和五种类型的动作做这件事。你可以在ineebapp2的15条路线中完成。但我看到我可以将其缩小到3或1.我不明白app.yaml定义将如何定义这种方法。 – 2012-01-16 08:53:14

+0

它不会,但这不是你在原始问题中提出的问题。实际上,我不确定它是如何关联的。 – 2012-01-16 10:20:54

回答

4

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中的值。