пирамида: обратный к add_notfound_view (append_slash = True) - PullRequest
5 голосов
/ 23 марта 2012

В Пирамида , add_notfound_view(append_slash=True) вызовет перенаправление запроса, который не соответствует ни одному представлению, но который будет соответствовать представлению, если в конце существует конечная косая черта, к соответствующему виду.

Существует ли обратное этому? То есть: если у меня есть маршрут, настроенный как

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

и пользователь запрашивает /reports/, существует ли простой способ заставить их перенаправляться соответствующим образом?

Ответы [ 2 ]

7 голосов
/ 24 марта 2012

Материал Майкла правильный.Вот код для последнего случая, в который он не вставил код:

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())
6 голосов
/ 24 марта 2012

Неглобальное решение

Добавьте второй маршрут для каждого вида, который вы хотите перенаправить.

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')

Глобально перенаправить все маршруты (никогда не поддерживаются косые черты)

Просто перепишите URL-адреса. Это можно сделать через pyramid_rewrite или внешне через ваш веб-сервер.

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

Попытка перенаправления, если маршрут не найден

Вырвите AppendSlashNotFoundFactory из источника пирамиды и переверните его. Извините, я не делаю этого для вас, но так же просто.

...