werkzeug Les URL de mappage de vues (via noeud final)
Question
Démarrage avec werkzeug, je tente de carte urls (à partir d'un urls.py de fichier) à vue (d'un point de vue de dossier, puis dans des fichiers différents pour gérer différents types de vue), mon organisation des dossiers ressemble que:
myapp/
application.py
urls.py
views/
__init__.py
common.py
places.py
...
mes fichiers urls.py ressemble à ça:
from werkzeug.routing import Map, Rule
url_map = Map([
Rule('/places', endpoint='places.overview')
])
et, évidemment, je suis arrivé ce morceau dans le fichier vues / places.py:
def overview(request):
mycode...
render_template('places.html', extra...)
La plupart des exemples de Werkzeug montrent l'utilisation du décorateur exposer à attacher urls à vue. Il est pratique pour une application avec 5 ou 6 urls mais peut devenir un enfer quand vous avez plus ...
Y at-il un moyen simple de cartographier les urls directement au
des vues
Merci.
La solution
Voici un exemple simplifié:
import views
def app(environ, start_response):
urls = url_map.bind_to_environ(environ)
request = Request(environ)
endpoint, params = urls.match()
names = endpoint.split('.')
view = views
for name in names:
if not hasattr(view, name):
__import__(view.__name__, None, None, [name])
view = getattr(view, name)
try:
response = view(request)
except werkzeug.exceptions.HTTPException, exc:
response = exc
return response(environ, start_response)
Autres conseils
import letters # our views module
url_map = Map([
Rule('/letters', endpoint=letters.index),
Rule('/letters/<int:item_id>', endpoint=letters.item),
Rule('/letters/<string:section_slug>', endpoint=letters.index),
Rule('/letters/<string:section_slug>/<int:item_id>',
endpoint=letters.item),
])
point final peut être quelque chose, y compris la fonction, de sorte que vous pouvez simplement ignorer la magie à l'importation de l'exemple de Denis
Je ne sais pas s'il est préféré façon d'aborder ce problème (je n'ai trouvé aucun exemple similaire dans repo werkzeug et je suis encore que jouer avec cette lib), mais il est également possible de la règle simplement sous-classe:
class CoolRule(Rule):
def __init__(self, view, *args, **kwargs):
self.view = view
super(CoolRule, self).__init__(*args, **kwargs)
def empty(self):
"""We need this method if we want to use
Submounts or Subdomain factories
"""
defaults = dict(self.defaults) if self.defaults else None
return CoolRule(self.view, self.rule, defaults, self.subdomain,
self.methods, self.build_only, self.endpoint,
self.strict_slashes, self.redirect_to,
self.alias, self.host)
_url_map = Map([
CoolRule(user.views.login, '/login', endpoint='user-login'),
CoolRule(user.views.logout, '/logout', endpoint='user-logout'),
])
def dispatch(request):
urls = _url_map.bind_to_environ(request.environ)
rule, arguments = urls.match(return_rule=True)
return rule.view(request, **arguments)
De cette façon, vous pouvez conserver la couche d'abstraction de nommage de vue et éviter la magie étrange. « Importation de chaîne »