Как сделать завершающую косую черту необязательной с помощью webapp2?
Я использую новый webapp2 (теперь используется webapp по умолчанию в версии 1.6), и мне не удалось выяснить, как сделать завершающую косую черту необязательной в этом коде:
webapp.Route('/feed', handler = feed)
Я пробовал /feed/?
, /feed/*
, /feed\/*
и /feed\/?
, все безрезультатно.
Ответы
Ответ 1
Чтобы избежать создания повторяющегося URL-адреса: s на той же странице, вы должны использовать RedirectRoute со строкой_slash, установленным в True, для автоматического перенаправления/подачи/в/фид, например:
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
Ответ 2
Мне не нравится класс RedirectRoute
, потому что он вызывает ненужную HTTP-переадресацию.
На основе документации для webapp2 класса маршрута, вот более подробный ответ в этом webapp2.Route с опцией ведущей части.
Короткий ответ
Мои шаблоны маршрутов работают для следующих URL-адресов.
- /
- /корма
- /корм/
- /корм/создать
- /корм/создать/
- /корм/редактировать/{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'),
]
Надеюсь, что это поможет: -)
Ответ 3
Вот как я обрабатываю эти маршруты.
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.
...
Ответ 4
webapp2.Route
template не является регулярным выражением, и ваше значение сбрасывается с помощью re.escape
. Вы можете использовать старые правила стиля, которые предоставляют шаблоны регулярных выражений:
webapp2.SimpleRoute('^/feed/?$', handler = feed)
Ответ 5
Я искал способ сделать косые черты в корне блока 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?
Ответ 6
Это работает для меня и очень просто. Он использует формат шаблона для маршрутизации URI в классе webapp2 Route . В этом примере трейлинг-косая черта необязательна без перенаправления:
webapp2.Route('/your_url<:/?>', PageHandler)
Все, что после двоеточия между шевронами считается регулярным выражением: <:regex>
Ответ 7
Если вы не хотите использовать перенаправления (и, вероятно, нет), вы можете переопределить 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
Ответ 8
Я придумал какой-то хакерский путь. Я определяю следующий класс:
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.
Ответ 9
Я не знаком с webapp2, но если первый параметр является регулярным выражением, попробуйте:
/feed(/)?