我的应用程序应该接受这样的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时间/托管费进行优化。例如,如果我为每个条目添加两行可能会更快:一行有类别而另一行没有类别...
答案 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之上添加我的解决方案作为免费答案 所以其他有下面问题的人可以得到更完整的答案。
此外,我想出了如何在一个正则表达式中路由/entity/create
和/entity/edit/{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类,其中包含 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')