金字塔:反向add_notfound_view(append_slash = True)

时间:2012-03-23 19:52:27

标签: pylons pyramid

Pyramid中,add_notfound_view(append_slash=True)会导致请求与任何视图都不匹配,但如果结尾存在尾随斜杠,那么匹配视图重定向到匹配视图。

是否存在与此相反的情况?即:如果我将路由配置为

config.add_route('list_reports', '/reports')

并且用户请求/reports/,是否有一种简单的方法可以使它们被适当地重定向?

2 个答案:

答案 0 :(得分:7)

迈克尔的东西是正确的。这里是他没有为代码输入的最后一个案例的代码:

from pyramid.httpexceptions import default_exceptionresponse_view, HTTPFound
from pyramid.interfaces import IRoutesMapper

class RemoveSlashNotFoundViewFactory(object):
    def __init__(self, notfound_view=None):
        if notfound_view is None:
            notfound_view = default_exceptionresponse_view
        self.notfound_view = notfound_view

    def __call__(self, context, request):
        if not isinstance(context, Exception):
            # backwards compat for an append_notslash_view registered via
            # config.set_notfound_view instead of as a proper exception view
            context = getattr(request, 'exception', None) or context
        path = request.path
        registry = request.registry
        mapper = registry.queryUtility(IRoutesMapper)
        if mapper is not None and path.endswith('/'):
            noslash_path = path.rstrip('/')
            for route in mapper.get_routes():
                if route.match(noslash_path) is not None:
                    qs = request.query_string
                    if qs:
                        noslash_path += '?' + qs
                    return HTTPFound(location=noslash_path)
        return self.notfound_view(context, request)

然后在您的主要配置中:

config.add_notfound_view(RemoveSlashNotFoundViewFactory())

答案 1 :(得分:6)

非全球解决方案

为要重定向的每个视图添加第二个路径。

config = Configurator()
def add_auto_route(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('list_reports', '/reports')

全局重定向所有路由(从不支持斜杠附加路由)

只需重写网址即可。这可以通过pyramid_rewrite完成,也可以通过Web服务器在外部完成。

config = Configurator()
config.include('pyramid_rewrite')
config.add_rewrite_rule(r'/(?P<path>.*)/', r'/%(path)s')

如果找不到路线,则尝试重定向

从金字塔的来源中翻出AppendSlashNotFoundFactory并将其反转。对不起,这里没有为你做这个,但同样容易。