如何使用webapp2选择尾随斜杠?

时间:2012-01-12 11:29:23

标签: python google-app-engine webapp2

我正在使用新的webapp2(现在是1.6中的默认webapp),而我无法弄清楚如何在这样的代码中使用尾随斜杠:

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

我尝试了/feed/?/feed/*/feed\/*/feed\/?,但都无济于事。

9 个答案:

答案 0 :(得分:13)

为避免在同一页面上创建重复的网址,您应使用RedirectRoute并将strict_slash设置为True以自动重定向/ Feed / to / feed,如下所示:

from webapp2_extras.routes import RedirectRoute

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

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

了解详情

答案 1 :(得分:7)

我不喜欢RedirectRoute类,因为它会导致不必要的 HTTP重定向
根据{{​​3}}的文档,这是webapp2 Route class主题中更详细的答案。

简答

我的路线模式适用于以下网址。

  1. /
  2. /进料
  3. /进料/
  4. /进料/创建
  5. /进料/创建/
  6. /进料/编辑/ {ENTITY_ID}
  7. 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'),
    ]
    

    希望它有所帮助: - )

答案 2 :(得分:4)

以下是我处理这些路线的方法。

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

请务必注意,处理程序需要定义*args**kwargs来处理潜在的尾部斜杠,并使用此方法将其作为参数发送给它们。

class Bar(webapp2.RequestHandler):

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

答案 3 :(得分:2)

webapp2.Route模板不是正则表达式,您的值将使用re.escape进行转义。您可以使用提供正则表达式模板的旧样式规则:

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

答案 4 :(得分:1)

我一直在寻找一种方法,可以在PathPrefixRoute块的根目录上设置trailling斜杠。

如果你有,请说:

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

您将能够访问/admin/,但不能访问/admin

由于我找不到更好的解决方案,我在一条额外的路线上添加了redirect_to_name,例如:

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

我对这个问题的更好解决方案感兴趣。

我应该使用Stun的解决方案而不使用RedirectRoute吗?

答案 5 :(得分:1)

这适合我,非常简单。它在webapp2 Route class中使用URI路由的模板格式。此示例中的尾部斜杠是可选的,没有重定向:

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

V形之间结肠后的所有东西都被认为是一个正则表达式:<:regex>

答案 6 :(得分:1)

如果您不想使用重定向(而您可能不使用),则可以覆盖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

答案 7 :(得分:0)

我想出了一种黑客的方式。我定义了以下类:

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

然后我按如下方式设置我的路线:

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

如果您确实选择了这条路线,那么您可以明显改进其他类型的BaseRoute对象。

答案 8 :(得分:-4)

我不熟悉webapp2,但如果第一个参数是正则表达式,请尝试:

/feed(/)?