Chaining Decorators

Pyramid has a decorator= argument to its view configuration. It accepts a single decorator that will wrap the mapped view callable represented by the view configuration. That means that, no matter what the signature and return value of the original view callable, the decorated view callable will receive two arguments: context and request and will return a response object:

 1# the decorator
 2
 3def decorator(view_callable):
 4    def inner(context, request):
 5        return view_callable(context, request)
 6    return inner
 7
 8# the view configuration
 9
10@view_config(decorator=decorator, renderer='json')
11def myview(request):
12    return {'a':1}

But the decorator argument only takes a single decorator. What happens if you want to use more than one decorator? You can chain them together:

 1def combine(*decorators):
 2    def floo(view_callable):
 3        for decorator in decorators:
 4            view_callable = decorator(view_callable)
 5        return view_callable
 6    return floo
 7
 8def decorator1(view_callable):
 9    def inner(context, request):
10        return view_callable(context, request)
11    return inner
12
13def decorator2(view_callable):
14    def inner(context, request):
15        return view_callable(context, request)
16    return inner
17
18def decorator3(view_callable):
19    def inner(context, request):
20        return view_callable(context, request)
21    return inner
22
23alldecs = combine(decorator1, decorator2, decorator3)
24two_and_three = combine(decorator2, decorator3)
25one_and_three = combine(decorator1, decorator3)
26
27@view_config(decorator=alldecs, renderer='json')
28def myview(request):
29    return {'a':1}