webapp2.Route с необязательной ведущей частью - PullRequest
4 голосов
/ 13 августа 2011

Я изучаю webapp2 фреймворк с его мощным механизмом Route .

Мое приложение должно принимать такие URI:

/poll/abc-123
/poll/abc-123/
/poll/abc-123/vote/       # post new vote
/poll/abc-123/vote/456    # view/update a vote

Опросы могут быть организованы по категориям, поэтому все вышеперечисленное должно также работать следующим образом:

/mycategory/poll/abc-123
/mycategory/poll/abc-123/
/mycategory/poll/abc-123/vote/
/mycategory/poll/abc-123/vote/456

Моя неверная конфигурация:

app = webapp2.WSGIApplication([
    webapp2.Route('/<category>/poll/<poll_id><:/?>', PollHandler),
    webapp2.Route('/<category>/poll/<poll_id>/vote/<vote_id>', VoteHandler),
], debug=True)

Вопрос: Как мне исправить мою конфигурацию?

Если возможно, его следует оптимизировать для процессорного времени GAE / платы за хостинг. Например, может быть быстрее, если я добавлю две строки для каждой записи: одну строку с категорией и другую без категории ...

Ответы [ 2 ]

7 голосов
/ 13 августа 2011

webapp2 имеет механизм для повторного использования общих префиксов, но в этом случае они различаются, поэтому вы не можете избежать дублирования этих маршрутов, как в:

app = webapp2.WSGIApplication([
    webapp2.Route('/poll/<poll_id><:/?>', PollHandler),
    webapp2.Route('/poll/<poll_id>/vote/<vote_id>', VoteHandler),
    webapp2.Route('/<category>/poll/<poll_id><:/?>', PollHandler),
    webapp2.Route('/<category>/poll/<poll_id>/vote/<vote_id>', VoteHandler),
], debug=True)

Вам не нужно беспокоиться о добавлении множества маршрутов. Они действительно дешевы в сборке и подборе. Если у вас нет десятков тысяч, сокращение количества маршрутов не будет иметь значения.

Небольшое примечание: первый маршрут принимает дополнительный конец косой черты. Вместо этого вы можете использовать RedirectRoute для принятия только одного и перенаправления, если к другому обращаются, используя опцию strict_slash=True. Это не очень хорошо задокументировано, но уже давно. См. Объяснение в строке документации .

1 голос
/ 19 декабря 2012

Я собираюсь добавить свое решение к этому как бесплатный ответ поверх @ moraes.
Так что другие люди, имеющие проблемы, подобные приведенным ниже, могут получить более полный ответ.

  1. Проблема с косой чертой
  2. Проблема с дополнительными параметрами

Кроме того, я понял, какroute и /entity/create и /entity/edit/{id} в одном регулярном выражении.
Ниже приведены мои маршруты, которые поддерживают следующие шаблоны URL.

  1. /
  2. / myentities
  3. / myentities /
  4. / myentities / create
  5. / myentities / create /
  6. / myentities / edit / {entity_id}
SITE_URLS = [
    webapp2.Route(r'/', handler=HomePageHandler, name='route-home'),

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

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

app = webapp2.WSGIApplication(SITE_URLS, debug=True)

Ниже мой BaseHandler, от которого наследуются все мои обработчики.

class BaseHandler(webapp2.RequestHandler):
    @webapp2.cached_property
    def jinja2(self):
        # Sets the defaulte templates folder to the './app/templates' instead of 'templates'
        jinja2.default_config['template_path'] = s.path.join(
            os.path.dirname(__file__),
            'app',
            'templates'
        )

        # Returns a Jinja2 renderer cached in the app registry.
        return jinja2.get_jinja2(app=self.app)

    def render_response(self, _template, **context):
        # Renders a template and writes the result to the response.
        rv = self.jinja2.render_template(_template, **context)
        self.response.write(rv)

Ниже мой класс MyEntityHandler python с get() сигнатурой метода для API хранилища данных Google App Engine .

class MyEntityHandler(BaseHandler):
    def get(self, entity_id, **kwargs):
        if entity_id:
            entity = MyEntity.get_by_id(int(entity_id))
            template_values = {
                'field1': entity.field1,
                'field2': entity.field2
            }
        else:
            template_values = {
                'field1': '',
                'field2': ''
            }
    self.render_response('my_entity_create_edit_view_.html', **template_values)



    def post(self, entity_id, **kwargs):
        # Code to save to datastore. I am lazy to write this code.

        self.redirect('/myentities')
...