我正在使用新的 webapp2(现在是 1.6 中的默认 webapp),但我无法弄清楚如何在这样的代码中使尾部斜杠成为可选:
webapp.Route('/feed', handler = feed)
我试过/feed/?
,和/feed/*
,都无济于事。/feed\/*
/feed\/?
我正在使用新的 webapp2(现在是 1.6 中的默认 webapp),但我无法弄清楚如何在这样的代码中使尾部斜杠成为可选:
webapp.Route('/feed', handler = feed)
我试过/feed/?
,和/feed/*
,都无济于事。/feed\/*
/feed\/?
为避免在同一页面上创建重复的 URL:s,您应该使用将 strict_slash 设置为 True 的 RedirectRoute 自动将 /feed/ 重定向到 /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阅读更多内容
我不喜欢这个RedirectRoute
类,因为它会导致不必要的HTTP Redirect。
根据webapp2 Route class的文档,这里有一个更详细的答案,在这个webapp2.Route 中带有可选的前导部分线程。
简答
我的路由模式适用于以下 URL。
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'),
]
希望能帮助到你 :-)
以下是我处理这些路线的方法。
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.
...
webapp2.Route
模板不是正则表达式,您的值正在使用re.escape
. 您可以使用提供正则表达式模板的旧式规则:
webapp2.SimpleRoute('^/feed/?$', handler = feed)
我正在寻找一种方法来使 PathPrefixRoute 块的根上的尾随斜杠可选。
如果有,请说:
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 吗?
这对我有用,而且非常简单。它在 webapp2 Route类中使用模板格式进行 URI 路由。此示例中的尾部斜杠是可选的,没有重定向:
webapp2.Route('/your_url<:/?>', PageHandler)
人字形之间的冒号之后的所有内容都被认为是一个正则表达式:<:regex>
如果您不想使用重定向(并且您可能不想),您可以覆盖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
我想出了一种 hacky 方式。我定义了以下类:
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 对象更加灵活。
我对webapp2不熟悉,但是如果第一个参数是正则表达式,试试:
/feed(/)?