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.

Références