2011-08-13 3 views
4

J'apprends le cadre webapp2 avec son puissant mécanisme Route.webapp2.Route avec partie avant facultative

Mon application est censé accepter URIs comme ceux-ci:

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

Les sondages peuvent éventuellement être organisés en catégories, de sorte que tous les devraient travailler dessus aussi comme ceci:

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

Ma configuration incorrecte:

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

question: Comment pourrais-je réparer ma configuration?

Si possible, il devrait être optimisé pour GAE CPU-temps/frais d'hébergement. Par exemple, il peut être plus rapide si j'ajoute deux lignes pour chaque entrée: une ligne avec catégorie et une autre sans catégorie ...

Répondre

7

webapp2 a un mécanisme pour réutiliser les préfixes communs, mais dans ce cas ils varient, donc vous ne peuvent pas éviter de dupliquer ces routes, comme dans:

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) 

Vous ne devriez pas vous soucier d'ajouter de nombreuses routes. Ils sont vraiment bon marché à construire et correspondre. Sauf si vous avez des dizaines de milliers, la réduction du nombre de routes n'aura pas d'importance.

Petite note: la première route accepte une barre oblique en option. Vous pouvez à la place utiliser le RedirectRoute pour n'en accepter qu'un seul et rediriger si l'autre est accédé, en utilisant l'option strict_slash=True. Ce n'est pas bien documenté mais a été autour pendant un moment. Voir le explanation in the docstring.

+0

Merci beaucoup, Rodrigo! – zengabor

1

Je vais ajouter ma solution à cette question en guise de réponse complémentaire à @moraes.
Alors d'autres personnes ayant des problèmes comme ci-dessous peuvent obtenir une réponse plus complète.

  1. Trailing Slash Problem
  2. Optional Parameter Problem

En outre, je compris comment acheminer les /entity/create et /entity/edit/{id} dans un regex.
Voici mes routes qui prennent en charge les modèles d'URL suivants.

  1. /
  2. /myentities
  3. /myentities/
  4. /myentities/créer
  5. /myentities/créer/
  6. /myentities/modifier/{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) 

Voici mon BaseHandler dont tous mes gestionnaires héritent.

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) 

Ci-dessous est ma classe MyEntityHandler python avec la signature de méthode get() pour l'API Google App Engine Datastore.

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