Chris
Chris

Reputation: 1643

Pyramid: Default values in route pattern

I was wondering:
Is it possible, to provide default values within the pattern of a route configuration?
For example: I have a view that shows a (potentially large) list of files bound to a data set. I want to split up the view in pages, which each page showing 100 files. When the page part in the url pattern is omitted, I want the first page to be shown.
So I'd like to have something like:

config.add_route('show_files', '/show_files/{datasetid}/{page=1})

Is that, or an alternative doable with reasonable effort? I haven't found anything in the route syntax description in the pyramid documentation.

Thanks a lot!

Upvotes: 4

Views: 3625

Answers (4)

Amber
Amber

Reputation: 527328

No, but you can use a remainder match to make the page optional, and then decide what page to show in your actual logic.

http://readthedocs.org/docs/pyramid/en/main/narr/urldispatch.html

The other option is to simply have your page be a GET variable rather than part of the URL.

Upvotes: 2

Jason Cross
Jason Cross

Reputation: 11

I was not able to get Thomas Jungs example to work. I was able to get Thomas Jung's example working by iterating the key without using iteritems().

def matchdict_default(**kw):
def f(info, request):
    for k in kw:
        info['match'].setdefault(k, kw[k])
    return True
return f

config.add_route(
'show_files', 
'/show_files/{datasetid}/{page}')
config.add_route(
'show_files', 
'/show_files/{datasetid}', 
custom_predicates=(matchdict_default(page=1),))`

now both of the following urls resolve to the page value, and, urls
can be created without needing to include a query
parameter

/show_files/an_id/
/show_files/an_id/?page=1

Upvotes: 0

Thomas Jung
Thomas Jung

Reputation: 33092

A (hacky) way to set this up is to use a custom predicate. Changing the matchdict is explicitly allowed.

def matchdict_default(**kw):
    def f(info, request):
        for k, v in kw.iteritems():
            info['match'].setdefault(k, v)
        return True
    return f

config.add_route(
    'show_files', 
    '/show_files/{datasetid}/{page}')
config.add_route(
    'show_files', 
    '/show_files/{datasetid}', 
    custom_predicates=(matchdict_default(page=1),))

Upvotes: 1

Michael Merickel
Michael Merickel

Reputation: 23331

You're probably content with this answer, but another option is to use multiple routes that dispatch to the same view.

config.add_route('show_files', '/show_files/{datasetid}')
config.add_route('show_files:page', '/show_files/{datasetid}/{page}')

@view_config(route_name='show_files')
@view_config(route_name='show_files:page')
def show_files_view(request):
    page = request.matchdict.get('page', '1')

Upvotes: 14

Related Questions