Rutas con barras al final en la pirámide

Digamos que tengo una ruta ‘/ foo / bar / baz’. También me gustaría tener otra vista correspondiente a ‘/ foo’ o ‘/ foo /’. Pero no quiero agregar sistemáticamente barras diagonales de seguimiento para otras rutas, solo para / foo y algunas otras (/ buz pero no / biz)

Por lo que vi, no puedo simplemente definir dos rutas con el mismo nombre de ruta. Actualmente hago esto:

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

¿Hay algo más elegante en Pyramid para hacer esto?

Encontré esta solución cuando buscaba lo mismo para mi proyecto.

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

Y luego, durante la configuración de la ruta,

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

En lugar de hacer config.add_route('events','/events')

Básicamente es un híbrido de tus métodos. Se define una nueva ruta cuyo nombre termina en _auto y su vista redirige a la ruta original.

EDITAR

La solución no tiene en cuenta los componentes dynamics de URL y los parámetros GET. Para una URL como /abc/{def}?m=aasa , el uso de add_auto_route() generará un error de clave porque la función del redirector no tiene en cuenta request.matchdict . El código de abajo hace eso. Para acceder a los parámetros GET también usa _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') 

Pyramid tiene una manera para que HTTPNotFound vistas de HTTPNotFound automáticamente una barra y prueben las rutas nuevamente para una coincidencia (la forma en que APPEND_SLASH=True de Django APPEND_SLASH=True funciona de APPEND_SLASH=True ). Echa un vistazo a:

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

Según este ejemplo, puede usar config.add_notfound_view(notfound, append_slash=True) , donde notfound es una función que define su vista HTTPNotFound . Si no se encuentra una vista (porque no coincidió debido a una barra diagonal faltante), la vista HTTPNotFound agregará una barra e intentará nuevamente. El ejemplo que se muestra en el enlace de arriba es bastante informativo, pero avíseme si tiene alguna pregunta adicional.

Además, preste atención a la advertencia de que esto no debe utilizarse con las solicitudes POST.

También hay muchas formas de despellejar a un gato en Pyramid, así que puedes jugar y lograr esto de diferentes maneras, pero ahora tienes el concepto.

Encontré otra solución. Parece que podemos encadenar dos @view_config. Entonces esta solución es posible:

 @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 

Su comportamiento también es diferente de la pregunta. La solución de la pregunta realiza una redirección, por lo que la url cambia en el navegador. En la segunda forma, tanto / foo como / foo / pueden aparecer en el navegador, dependiendo de lo que haya ingresado el usuario. Realmente no me importa, pero repetir la ruta del renderizador también es incómodo.