Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pyramid: Routing schemas and restraints

I have done my research and did some pattern matching trials but I still can not figure out how to:

  1. Make part of the route optional. e.g.:

    /required (/optional/{str}) Here the part in parentheses is optional.

  2. Apply restraints to routing so instead of a wildcard string, it has to match an item from a tuple.

    /view_1/ {('opt_a', 'opt_b', 'opt_c' ...)} in this case, if an item from the tuple is matched, it routes if not 404 or FORBIDDEN

How can I achieve these?

Thank you.

like image 256
Phil Avatar asked Jun 21 '12 10:06

Phil


1 Answers

Pyramid does not support optional patterns in a route. The other answer suggests *optional but this will match much more than what you asked for which was one optional placeholder, and leaves you with no options at the end of the route for more patterns.

config.add_route('name_with_optional', '/required/{optional}/{str}')
config.add_route('name', '/required/{str}')

Now you want to use the same view for both I imagine, since you are thinking of the placeholder as optional. Thus, simply register the view for both cases:

@view_config(route_name='name_with_optional')
@view_config(route_name='name')
def my_view(request):
    optional = request.matchdict.get('optional')

The optional variable will be None if 'name' was the matched route pattern.

As for your second question, you can simply create a custom predicate. This could be either on the route or the view (remember that these are separate in Pyramid). The signature for the predicate is different in each case.

A predicate on the route (less common):

def opt_must_contain(info, request):
    opt = info['match'].get('opt')
    return opt in ('opt_a', 'opt_b', 'opt_c')

config.add_route('my_route', '/view_1/{opt}', custom_predicates=[opt_must_contain])

If this predicate returns False then another route with the same pattern could be matched (the route is ignored).

A predicate on the view (more common):

def opt_must_contain(context, request):
    opt = request.matchdict.get('opt')
    return opt in ('opt_a', 'opt_b', 'opt_c')

config.add_route('my_route', '/view_1/{opt}')

@view_config(route_name='my_route', custom_predicates=[opt_must_contain])
def my_view(request):
    opt = request.matchdict.get('opt')

In the view we'll know opt is one of the required options.

like image 93
Michael Merickel Avatar answered Sep 21 '22 12:09

Michael Merickel