在金字塔中使用尾部斜杠的路线

asc*_*bol 7 python url-routing pyramid

假设我有一条'/ foo/bar/baz'路线.我还希望有另一个对应于'/ foo'或'/ foo /'的视图.但是我不想系统地为其他路径添加尾部斜杠,仅用于/ foo和其他几个(/ buz但不是/ biz)

从我看到的我不能简单地定义具有相同route_name的两个路由.我目前这样做:

config.add_route('foo', '/foo')
config.add_route('foo_slash', '/foo/')
config.add_view(lambda _,__: HTTPFound('/foo'), route_name='foo_slash')
Run Code Online (Sandbox Code Playgroud)

金字塔中有更优雅的东西吗?

Raj*_*Raj 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请求一起使用.

在金字塔中有很多方法可以让猫皮肤变形,所以你可以用不同的方式来玩耍,但是你现在有这个概念.

  • 好的,抱歉.我会留下这个回复,只是为了谷歌,以防任何人实际上正在寻找这种方法. (5认同)

Red*_*ron 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')
Run Code Online (Sandbox Code Playgroud)

然后在路由配置时,

add_auto_route(config,'events','/events')
Run Code Online (Sandbox Code Playgroud)

而不是做config.add_route('events','/events')

基本上它是你的方法的混合。定义了一条名称以 结尾的新路由,_auto并且其视图重定向到原始路由。

编辑

该解决方案不考虑动态 URL 组件和 GET 参数。对于像这样的 URL /abc/{def}?m=aasa,使用add_auto_route()会抛出关键错误,因为该redirector函数没有考虑到request.matchdict。下面的代码就是这样做的。为了访问 GET 参数,它还使用_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')
Run Code Online (Sandbox Code Playgroud)