7

'/foo/bar/baz' というルートがあるとします。「/foo」または「/foo/」に対応する別のビューも必要です。ただし、他のルートの末尾にスラッシュを体系的に追加したくはありません。/foo と他のいくつか (/biz ではなく /buz) に対してのみです。

私が見たところ、同じ route_name を持つ 2 つのルートを単純に定義することはできません。私は現在これを行います:

config.add_route('foo', '/foo')
config.add_route('foo_slash', '/foo/')
config.add_view(lambda _,__: HTTPFound('/foo'), route_name='foo_slash')

これを行うために Pyramid でよりエレガントなものはありますか?

4

3 に答える 3

11

Pyramid には、HTTPNotFoundビューが自動的にスラッシュを追加し、ルートが一致するかどうかを再度テストする方法があります (Django のAPPEND_SLASH=True動作方法)。を見てみましょう:

http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/urldispatch.html#redirecting-to-slash-appended-routes

この例のように、 を使用できますconfig.add_notfound_view(notfound, append_slash=True)。ここで、notfoundはビューを定義する関数ですHTTPNotFound。ビューが見つからない場合 (スラッシュがないために一致しなかったため)、HTTPNotFoundビューはスラッシュを追加して再試行します。上記のリンクに示されている例は非常に有益ですが、他に質問がある場合はお知らせください。

また、これは POST リクエストでは使用しないでください。

Pyramid で猫の皮を剥ぐ方法もたくさんあるので、さまざまな方法で遊んでこれを達成することもできますが、今ではコンセプトができています。

于 2013-03-29T18:00:11.437 に答える
3

プロジェクトで同じものを探していたときに、このソリューションを見つけました

def add_auto_route(config,name, pattern, **kw):
    config.add_route(name, pattern, **kw)
    if not pattern.endswith('/'):
        config.add_route(name + '_auto', pattern + '/')
        def redirector(request):
            return HTTPMovedPermanently(request.route_url(name))
        config.add_view(redirector, route_name=name + '_auto')

そして、ルート構成中に、

add_auto_route(config,'events','/events')

するのではなくconfig.add_route('events','/events')

基本的に、それはあなたの方法のハイブリッドです。で終わる名前の新しいルート_autoが定義され、そのビューは元のルートにリダイレクトされます。

編集

このソリューションでは、動的 URL コンポーネントと GET パラメータは考慮されていません。のような URL の場合、関数は を考慮しないため/abc/{def}?m=aasa、 を使用add_auto_route()するとキー エラーがスローされます。以下のコードはそれを行います。GET パラメータにアクセスするためにも使用しますredirectorrequest.matchdict_query=request.GET

def add_auto_route(config,name, pattern, **kw):
    config.add_route(name, pattern, **kw)
    if not pattern.endswith('/'):
        config.add_route(name + '_auto', pattern + '/')
        def redirector(request):
            return HTTPMovedPermanently(request.route_url(name,_query=request.GET,**request.matchdict))
        config.add_view(redirector, route_name=name + '_auto')
于 2013-03-29T14:58:15.803 に答える
1

別の解決策を見つけました。2 つの @view_config をチェーンできるようです。したがって、この解決策は可能です:

@view_config(route_name='foo_slash', renderer='myproject:templates/foo.mako')    
@view_config(route_name='foo', renderer='myproject:templates/foo.mako')
def foo(request):
   #do something

その振る舞いも質問とは異なります。質問の解決策はリダイレクトを実行するため、ブラウザーで URL が変更されます。2 番目の形式では、ユーザーが入力した内容に応じて、/foo と /foo/ の両方がブラウザーに表示されます。私はあまり気にしませんが、レンダラーのパスを繰り返すのも厄介です。

于 2013-03-29T14:47:19.953 に答える