Pregunta

Estoy usando el nuevo WebApp2 (ahora la WebApp predeterminada en 1.6), y no he podido averiguar cómo hacer que la barra de arrastre sea opcional en un código como este:

webapp.Route('/feed', handler = feed)

He intentado /feed/?, /feed/*, /feed\/* y /feed\/?, todo fue en vano.

¿Fue útil?

Solución

Para evitar la creación de URL duplicada: S en la misma página, debe usar un redirectruteute con Strict_Slash establecido en True para redirigir automáticamente /Feed /To /Feed, como este:

from webapp2_extras.routes import RedirectRoute

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

Lee mas en http://webapp2.readthedocs.io/en/latest/api/webapp2_extras/routes.html

Otros consejos

No me gusta el RedirectRoute clase porque causa un innecesario HTTP Redirección.
Basado en la documentación para clase de ruta webapp2, aquí hay una respuesta más detallada en este WebApp2.Route con una parte líder opcional hilo.

Respuesta corta

Mis patrones de ruta funcionan para las siguientes URL.

  1. /
  2. /alimento
  3. /alimento/
  4. /alimentar/crear
  5. /alimentar/crear/
  6. /feed/edit/{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 eso ayude :-)

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 manejadores deberán definir *args y **kwargs Para lidiar con la posible barra de arrastre, que se les envía como argumento utilizando este método.

class Bar(webapp2.RequestHandler):

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

webapp2.Route La plantilla no es una expresión regular y su valor se está escapando con re.escape. Puede usar reglas de estilo antiguas que proporcionan plantillas de expresión regulares:

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

Esto funciona para mí y es muy simple. Utiliza el formato de plantilla para el enrutamiento de URI en la ruta WebApp2 clase. La barra de arrastre en este ejemplo es opcional sin redirección:

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

Todo después del colon entre los Chevrons se considera un Regex: <:regex>

Si no desea usar redireccionamientos (y probablemente no lo hace), 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

Estaba buscando una manera de hacer que la barra de trailización en la raíz de un bloque Pathprefixroute sea opcional.

Si lo ha hecho, diga:

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),
  ]),
])

Podrás acceder /admin/, pero no /admin.

Como no pude encontrar una mejor solución, he agregado un 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 mejores soluciones a este problema.

¿Debo ir a la solución de Stun y simplemente no usar redirectroute?

Se me ocurrió una especie de camino hacky. Defino la siguiente clase:

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 configuré mis rutas como las siguientes:

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 elige seguir esta ruta, obviamente puede mejorarla para que sea más flexible con otros tipos de objetos Baseroute.

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

/feed(/)?
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top