2012-01-12 10 views

Respuesta

13

Para evitar la creación duplicado URL: s a la misma página, se debe utilizar un RedirectRoute con strict_slash se establece en True para redirigir automáticamente/alimentación/a/alimentación , de esta manera:

from webapp2_extras.routes import RedirectRoute 

route = RedirectRoute('/feed', handler=feed, strict_slash=True) 

Ver más en http://webapp2.readthedocs.io/en/latest/api/webapp2_extras/routes.html

+1

Gracias. ¿Quiere decir que si tengo cien rutas, también necesito cien redirectroutes? Parece una solución terriblemente desordenada. –

+1

Hola. No, reemplazas las rutas con RedirectRoutes, por lo que no necesitas ambas. RedirectRoute hace todo lo que hace Route, pero también agrega la opción "strict_slash", así como algunas otras funcionalidades de redirección. Mira el enlace que publiqué arriba para más detalles. – Aneon

+0

Esto no siempre es una buena idea. Si su cliente no es un navegador web (por ejemplo, si está escribiendo una API accesible para su sitio web), es posible que no siga el redireccionamiento. – Ponkadoodle

-4

No estoy familiarizado con webapp2, pero si el primer parámetro es una expresión regular, trato:

/feed(/)? 
2

webapp2.Route plantilla no es una de las expresiones regulares y su valor se escapó con re.escape. Puede utilizar las reglas de estilo antiguo que proporciona plantillas de expresiones regulares:

webapp2.SimpleRoute('^/feed/?$', handler = feed) 
+0

quiero seguir usando la sintaxis propia webapps' sin descender a las expresiones regulares regulares. .. en ese sentido, 'strict_slash' me da exactamente lo que quiero con el mínimo cambio de código. –

7

no me gusta la clase RedirectRoute porque causa una innecesaria Redirección HTTP.
Según la documentación para webapp2 Route class, aquí hay una respuesta más detallada en este subproceso webapp2.Route with optional leading part.

de respuesta breve

Mis patrones de ruta sirve para la siguiente URL.

  1. /
  2. /alimentar
  3. /alimentación/
  4. /alimentación/crear
  5. /alimentación/creación/
  6. /alimentación/editar/{entity_id}
SITE_URLS = [ 
    webapp2.Route(r'/', handler=HomePageHandler, name='route-home'), 

    webapp2.Route(r'/feed/<:(create/?)|edit/><entity_id:(\d*)>', 
     handler=MyFeedHandler, 
     name='route-entity-create-or-edit'), 

    webapp2.SimpleRoute(r'/feed/?', 
     handler=MyFeedListHandler, 
     name='route-entity-list'), 
] 

Espero que ayude :-)

4

Así es como manejo estas rutas.

from webapp2 import Route 
from webapp2_extras.routes import PathPrefixRoute 
import handlers 

urls = [ 
    Route('/foo<:/?>', handlers.Foo), 
    Route('/bars', handlers.BarList), 
    PathPrefixRoute('/bar', [ 
    Route('/', handlers.BarList), 
    Route('/<bar_id:\w+><:/?>', handlers.Bar), 
    ]), 
] 
... 

Es importante tener en cuenta que sus manipuladores deberán definir *args y **kwargs que lidiar con el potencial barra final, que se envía a ellos como un argumento que utiliza este método.

class Bar(webapp2.RequestHandler): 

    def get(bar_id, *args, **kwargs): 
    # Lookup and render this Bar using bar_id. 
    ... 
1

Estaba buscando una forma de hacer que la barra inclinada en la raíz de un bloque PathPrefixRoute sea opcional.

Si usted tiene, dicen:

from webapp2_extras.routes import RedirectRoute, PathPrefixRoute 

from webapp2 import Route 

app = webapp2.WSGIApplication([ 
    PathPrefixRoute('admin', [ 
     RedirectRoute('/', handler='DashboardHandler', name='admin-dashboard', strict_slash=True), 
     RedirectRoute('/sample-page/', handler='SamplePageHandler', name='sample-page', strict_slash=True), 
    ]), 
]) 

usted será capaz de acceder /admin/, pero no /admin.

Como no podía encontrar ninguna solución mejor, ¡Tengo una redirect_to_name a una ruta adicional, como:

from webapp2_extras.routes import RedirectRoute, PathPrefixRoute 

from webapp2 import Route 

app = webapp2.WSGIApplication([ 
    Route('admin', handler='DashboardHandler', name='admin-dashboard'), 
    PathPrefixRoute('admin', [ 
     RedirectRoute('/', redirect_to_name='admin-dashboard'), 
     RedirectRoute('/sample-page/', handler='SamplePageHandler', name='sample-page', strict_slash=True), 
    ]), 
]) 

Estoy interesado en recibir mejores soluciones a este problema.

¿Debo buscar la solución de Stun y simplemente no usar RedirectRoute?

+0

Puede intentar mi solución: http://stackoverflow.com/a/22223617/1175629 –

1

Esto funciona para mí y es muy simple. Utiliza el formato de plantilla para el enrutamiento URI en la ruta webapp2 class. Barra final en este ejemplo es opcional sin redirección:

webapp2.Route('/your_url<:/?>', PageHandler) 

Todo después de los dos puntos entre los galones se considera que es una expresión regular: <:regex>

+0

Merece la pena señalar que sus métodos necesitan un argumento adicional, que es un poco asqueroso. – alex

+0

Paso '' args, ** kwargs' en mis métodos de todos modos, por lo que el 'get' para' PageHandler' sería 'def get (self, * args, ** kwargs)' – HorseloverFat

0

me ocurrió con una clase de manera hacky. Yo defino la clase siguiente:

class UrlConf(object): 

    def __init__(self, *args, **kwargs): 
     self.confs = [] 
     for arg in args: 
      if isinstance(arg, webapp2.Route): 
       slash_route = webapp2.Route(arg.template + '/', arg.handler) 
       self.confs += [arg, slash_route] 

    def __iter__(self): 
     for route in self.confs: 
      yield route 

Luego he creado mis rutas como la siguiente:

MIRROR_URLS = list(UrlConf(
    Route('/path/to/stuff', handler=StuffHandler, name='stuff.page'), 
    Route('/path/to/more/stuff', handler= MoreStuffHandler, name='more.stuff.page') 
)) 

Si decide seguir este camino, es obvio que puede mejorar para ser más flexible con otros tipos de objetos BaseRoute.

1

Si no desea utilizar las redirecciones (y es probable que no), puede anular Route.match():

from webapp2 import Route, _get_route_variables 
import urllib 
from webob import exc 


class SloppyRoute(Route): 
    """ 
    A route with optional trailing slash. 
    """ 
    def __init__(self, *args, **kwargs): 
     super(SloppyRoute, self).__init__(*args, **kwargs) 

    def match(self, request): 
     path = urllib.unquote(request.path) 
     match = self.regex.match(path) 
     try: 
      if not match and not path.endswith('/'): 
       match = self.regex.match(path + '/') 
     except: 
      pass 
     if not match or self.schemes and request.scheme not in self.schemes: 
      return None 

     if self.methods and request.method not in self.methods: 
      # This will be caught by the router, so routes with different 
      # methods can be tried. 
      raise exc.HTTPMethodNotAllowed() 

     args, kwargs = _get_route_variables(match, self.defaults.copy()) 
     return self, args, kwargs 
Cuestiones relacionadas