Subpath Predicate

One problem with pyramid’s traversal mechanism is that it doesn’t allow you to set view predicates on the subpath. If you aren’t already intimately familiar with the details of resource lookup via traversal, here are the docs.

So we’ve got the context, which is the last found resource. The name, which is the first url segment that had no new context, and then the subpath, which is all path components after the name.

To enforce a subpath matching, pass in a list or tuple as the vew predicate:

@view_config(context=MyCtxt, name='foobar', subpath=())
def my_view(request):
    # do things

Assuming that MyCtxt maps to /mything, this view will match /mything/foobar and /mything/foobar/ only. No subpath allowed. Here is the format for matching a single subpath:

@view_config(context=MyCtxt, name='foobar', subpath=('post', '*'))
def my_view(request):
    id = request.subpath[0]
    # do things

You can name the subpaths and access them by name:

@view_config(context=MyCtxt, name='foobar', subpath=('post', 'id/*'))
def my_view(request):
    id = request.named_subpaths['id']
    # do things

And there are flags you can pass in that allow, among other things, PCRE matching:

@view_config(context=MyCtxt, name='foobar', subpath=('type/(post|tweet)/r', 'id/*'))
def my_view(request):
    item_type = request.named_subpaths['type']
    id = request.named_subpaths['id']
    # do things

Check the docs on SubpathPredicate for all of the formats, and match() for details on match flags.

Including

You can use this predicate by including pyramid_duh in your app (which comes with some other things), or if you only want the predicate you can include pyramid_duh.view:

config.include('pyramid_duh')

Or in the config file:

pyramid.includes =
    pyramid_duh