-->

How to generate URL to view when using Traversal?

2020-07-18 08:05发布

问题:

When URL Dispatch is used, we can easily generate a URL to a view because every view has a distinct route_name like:

login.py:
@view_config(route_name='login')

index.pt:
<a href="${request.route_url('login')}">Login</a>

But how to do this in traversal? Since there is no instance of resources 'Login' available, I don't know how to generate URL to view login.

回答1:

In traversal you are required to know the structure of your tree, and you must be able to load context objects on demand. The URLs are generated with respect to a context, using its location-aware properties __name__ and __parent__ to build the URL.

/
|- login
|- users
   |- 1
      |- edit

So let's say we have a User(id=1) context object, and we want to login. If your view is registered via @view_config(context=Root, name='login'), then you can generate the url via request.resource_url(request.root, 'login'). This is us telling Pyramid to generate a URL relative to the root of the tree.

On the other hand, if we are at login and we want to take the user to edit you must load a location-aware User object for that user in order to generate the URL. request.resource_url(user, 'edit') where user is an instance of User(id=1) with valid __name__ and __parent__ attributes.

If you pass in a context without a location-aware __parent__ the URL will be generated as if your user was mounted at / because that's the only sane place for Pyramid to think the object would be in your tree.

The ability to load a location-aware object is why we stress that traversal works best with a persistent tree of objects, not one that is generated on the fly. It's much more convenient to directly load the user and have its __parent__ and __name__ already populated for you if you want to generate URLs for it.



回答2:

resource_url(resource, 'view_name')