2012-01-11 85 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中的值。