webapp2.Route带有可选的前导部分

时间:2011-08-13 10:23:04

标签: google-app-engine webapp2

我正在学习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 CPU时间/托管费进行优化。例如,如果我为每个条目添加两行可能会更快:一行有类别而另一行没有类别...

2 个答案:

答案 0 :(得分:7)

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访问另一个时重定向。这没有很好的记录,但已经存在了一段时间。请参阅explanation in the docstring

答案 1 :(得分:1)

我将在@moraes之上添加我的解决方案作为免费答案 所以其他有下面问题的人可以得到更完整的答案。

  1. Trailing Slash Problem
  2. Optional Parameter Problem
  3. 此外,我想出了如何在一个正则表达式中路由/entity/create/entity/edit/{id}
    以下是支持以下网址格式的路线。

    1. /
    2. / myentities
    3. / myentities /
    4. / myentities /创建
    5. / myentities /创建/
    6. / myentities /编辑/ {ENTITY_ID}
    7. 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类,其中包含 Google App Engine数据存储区API get()方法签名。

      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')