2012-01-11 6 views
1

旧式のwebappでは、app.yamlベースのルーティングで正規表現をチェックでき、一致した場合、見つかったパターンに基づいた名前のハンドラでリクエストを処理します。例えば、\ 1_handler.pyは、一致したパターンが 'user'だった場合、user_handler.pyにディスパッチします。アドバンストWebapp2ルーティング

webapp2.Routeで同じことをする方法はありますか? lazyハンドラまたはmethod_handlerパラメータはテンプレートの一致パターンに基づいていますか?

+1

ここでは、app.yamlとWebフレームワークの2つの異なることについて話しています。 webapp2でapp.yamlベースのルーティングを引き続き使用できます。 –

+0

はいわかっています。しかし、私がしたいのは、URLの内容に基づいてリクエストハンドラクラス内の別のメソッドでリクエストを処理させることです。だから、もしそれがユーザ/ショーであれば、それはハンドラに行きたい:ショー、それがユーザ/追加の場合は、ユーザ:addに行きたい。 3種類のエンティティ(user + 2)と5種類のアクションについて、私はこれをやっています。あなたはineebapp2の15ルートでそれを行うことができます。しかし私はどのように3または1に絞り込むことができますか。私はapp.yamlの定義が私にメソを定義する方法を見ていない。 –

+0

それはしませんが、それは元の質問であなたが求めていたものではありません。私はそれがどのように関連しているのかは分かりません。 –

答えて

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}'), 
]) 

この例では、メソッド名にpatternの変数を使用することはできません(例:module.Class:action_{method})。 Routeクラスでは、このエンドポイントはセミコロンで分割され、値はroute.method_nameroute.handlerに格納されます。

関連する問題