Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
pyramid.pdf
Скачиваний:
10
Добавлен:
24.03.2015
Размер:
3.82 Mб
Скачать

25.5. VIEW LOOKUP

__getitem__ methods that search for files in specific directories, and thus precisely recreate the traditional mechanism of having the URL path mapped directly to a folder structure on the file system. Traversal is in fact a superset of file system lookup.

latex-note.png

See the chapter entitled Resources for a more technical overview of resources.

25.5 View Lookup

At this point we’re nearly there. We’ve covered traversal, which is the process by which a specific resource is retrieved according to a specific URL path. But what is “view lookup”?

The need for view lookup is simple: there is more than one possible action that you might want to take after finding a resource. With our photo example, for instance, you might want to view the photo in a page, but you might also want to provide a way for the user to edit the photo and any associated metadata. We’ll call the former the view view, and the latter will be the edit view. (Original, I know.) Pyramid has a centralized view application registry where named views can be associated with specific resource types. So in our example, we’ll assume that we’ve registered view and edit views for photo objects, and that we’ve specified the view view as the default, so that /joeschmoe/photos/photo1/view and /joeschmoe/photos/photo1 are equivalent. The edit view would sensibly be provided by a request for /joeschmoe/photos/photo1/edit.

Hopefully

it’s

clear

that the

first

portion of

the edit

view’s URL path is going to re-

solve to

the

same

resource

as the

non-edit

version,

specifically the resource returned by

get_root()[’joeschmoe’][’photos’][’photo1’]. But traveral ends there; the photo1 resource doesn’t have an edit key. In fact, it might not even be a dictionary-like object, in which case photo1[’edit’] would be meaningless. When the Pyramid resource location has been resolved to a leaf resource, but the entire request path has not yet been expended, the very next path segment is treated as a view name. The registry is then checked to see if a view of the given name has been specified for a resource of the given type. If so, the view callable is invoked, with the resource passed in as the related context object (also available as request.context). If a view callable could not be found, Pyramid will return a “404 Not Found” response.

You might conceptualize a request for /joeschmoe/photos/photo1/edit as ultimately converted into the following piece of Pythonic pseudocode:

277

25. MUCH ADO ABOUT TRAVERSAL

context = get_root()[’joeschmoe’][’photos’][’photo1’] view_callable = get_view(context, ’edit’) request.context = context

view_callable(request)

The get_root and get_view functions don’t really exist. Internally, Pyramid does something more complicated. But the example above is a reasonable approximation of the view lookup algorithm in pseudocode.

25.6 Use Cases

Why should we care about traversal? URL matching is easier to explain, and it’s good enough, right?

In some cases, yes, but certainly not in all cases. So far we’ve had very structured URLs, where our paths have had a specific, small number of pieces, like this:

/{userid}/{typename}/{objectid}[/{view_name}]

In all of the examples thus far, we’ve hard coded the typename value, assuming that we’d know at development time what names were going to be used (“photos”, “blog”, etc.). But what if we don’t know what these names will be? Or, worse yet, what if we don’t know anything about the structure of the URLs inside a user’s folder? We could be writing a CMS where we want the end user to be able to arbitrarily add content and other folders inside his folder. He might decide to nest folders dozens of layers deep. How will you construct matching patterns that could account for every possible combination of paths that might develop?

It might be possible, but it certainly won’t be easy. The matching patterns are going to become complex quickly as you try to handle all of the edge cases.

With traversal, however, it’s straightforward. Twenty layers of nesting would be no problem. Pyramid will happily call __getitem__ as many times as it needs to, until it runs out of path segments or until a resource raises a KeyError. Each resource only needs to know how to fetch its immediate children, the traversal algorithm takes care of the rest. Also, since the structure of the resource tree can live in the database and not in the code, it’s simple to let users modify the tree at runtime to set up their own personalized “directory” structures.

Another use case in which traversal shines is when there is a need to support a context-dependent security policy. One example might be a document management infrastructure for a large corporation, where

278

25.6. USE CASES

members of different departments have varying access levels to the various other departments’ files. Reasonably, even specific files might need to be made available to specific individuals. Traversal does well here if your resources actually represent the data objects related to your documents, because the idea of a resource authorization is baked right into the code resolution and calling process. Resource objects can store ACLs, which can be inherited and/or overridden by the subresources.

If each resource can thus generate a context-based ACL, then whenever view code is attempting to perform a sensitive action, it can check against that ACL to see whether the current user should be allowed to perform the action. In this way you achieve so called “instance based” or “row level” security which is considerably harder to model using a traditional tabular approach. Pyramid actively supports such a scheme, and in fact if you register your views with guard permissions and use an authorization policy, Pyramid can check against a resource’s ACL when deciding whether or not the view itself is available to the current user.

In summary, there are entire classes of problems that are more easily served by traversal and view lookup than by URL dispatch. If your problems don’t require it, great: stick with URL dispatch. But if you’re using Pyramid and you ever find that you do need to support one of these use cases, you’ll be glad you have traversal in your toolkit.

latex-note.png

It is even possible to mix and match traversal with URL dispatch in the same Pyramid application. See the Combining Traversal and URL Dispatch chapter for details.

279

25. MUCH ADO ABOUT TRAVERSAL

280

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]