Traversal et URL dispatch avec pyramid¶
On utilise au sein d’enDi à la fois le mécanisme de traversal et celui d’URL dispatch.
Le traversal nous permet, sur les vues concernées (option traverse
de add_view()
) d’attacher automatiquement à l’objet de requête HTTP, un objet métier (instance de modèle SQLAlchemy), à travers l’attribut request.context
.
On déclare donc des traversal puis on les attache à une ou plusieurs routes, ce qui rend le contexte accessible aux vues branchées sur ces routes.
Note
Ce document décrit l’usage qui est fait du traversal dans enDi, l’approche peut différer selon les projets.
Déclaration d’un traversal¶
Se fait dans endi.utils.security.RootFactory.leaves
avec un 3-uplet :
nom du traversal
nom du type d’objet (ça peuplera obj.__name__ automatiquement avec ce nom)
factory (la classe SQLAlchemy, qui doit avoir une propriété nommée
id
correspondant à l’id en BDD)
('companies', 'company', Company, ),
Utilisation d’un traversal pour une route donnée¶
On utilise add_route pour configurer le traversal à utiliser, pour reprendre l’exemple précédent :
config.add_route(
'/company/{id}/suppliers_orders',
'/company/{id}/suppliers_orders',
traverse='/companies/{id}',
)
Utilisation du contexte du traversal depuis la vue¶
Pour une vue mappée (via config.add_view) sur une route qui « traverse » un traversal :
l’attribut
request.context
contiendra l’objet automatiquement l’objet « traversé » .une 404 sera déclenchée si l’objet n’existe pas
l’éventuelle permission passée à add_view sera vérifiée pour l’utilisateur courant, sur l’objet traversé, pouvant déboucher sur une 403 si accès non autorisé.
Avertissement
Utiliser un traversal n’est pas suffisant pour protéger l’accès, il faut aussi requérir la bonne permission dans le add_view.
C’est là que se niche la magie : pyramid décompose l’URL tout seul pour établir
la correspondance entre /companies/{id} et le traversal nommé
companies
. Il est impératif d’avoir dans le pattern d’URL de la route un
champ {id}
qui sera utilisé pour récupérer automatiquement la Company
avec l’id correspondant.