|
1 "Functions that help with dynamically creating decorators for views." |
|
2 |
|
3 import types |
|
4 try: |
|
5 from functools import wraps |
|
6 except ImportError: |
|
7 from django.utils.functional import wraps # Python 2.3, 2.4 fallback. |
|
8 |
|
9 def decorator_from_middleware(middleware_class): |
|
10 """ |
|
11 Given a middleware class (not an instance), returns a view decorator. This |
|
12 lets you use middleware functionality on a per-view basis. |
|
13 """ |
|
14 def _decorator_from_middleware(*args, **kwargs): |
|
15 # For historical reasons, these "decorators" are also called as |
|
16 # dec(func, *args) instead of dec(*args)(func). We handle both forms |
|
17 # for backwards compatibility. |
|
18 has_func = True |
|
19 try: |
|
20 view_func = kwargs.pop('view_func') |
|
21 except KeyError: |
|
22 if len(args): |
|
23 view_func, args = args[0], args[1:] |
|
24 else: |
|
25 has_func = False |
|
26 if not (has_func and isinstance(view_func, types.FunctionType)): |
|
27 # We are being called as a decorator. |
|
28 if has_func: |
|
29 args = (view_func,) + args |
|
30 middleware = middleware_class(*args, **kwargs) |
|
31 |
|
32 def decorator_func(fn): |
|
33 return _decorator_from_middleware(fn, *args, **kwargs) |
|
34 return decorator_func |
|
35 |
|
36 middleware = middleware_class(*args, **kwargs) |
|
37 |
|
38 def _wrapped_view(request, *args, **kwargs): |
|
39 if hasattr(middleware, 'process_request'): |
|
40 result = middleware.process_request(request) |
|
41 if result is not None: |
|
42 return result |
|
43 if hasattr(middleware, 'process_view'): |
|
44 result = middleware.process_view(request, view_func, args, kwargs) |
|
45 if result is not None: |
|
46 return result |
|
47 try: |
|
48 response = view_func(request, *args, **kwargs) |
|
49 except Exception, e: |
|
50 if hasattr(middleware, 'process_exception'): |
|
51 result = middleware.process_exception(request, e) |
|
52 if result is not None: |
|
53 return result |
|
54 raise |
|
55 if hasattr(middleware, 'process_response'): |
|
56 result = middleware.process_response(request, response) |
|
57 if result is not None: |
|
58 return result |
|
59 return response |
|
60 return wraps(view_func)(_wrapped_view) |
|
61 return _decorator_from_middleware |