62 lines
2.4 KiB
Python
62 lines
2.4 KiB
Python
"Functions that help with dynamically creating decorators for views."
|
|
|
|
import types
|
|
try:
|
|
from functools import wraps
|
|
except ImportError:
|
|
from django.utils.functional import wraps # Python 2.3, 2.4 fallback.
|
|
|
|
def decorator_from_middleware(middleware_class):
|
|
"""
|
|
Given a middleware class (not an instance), returns a view decorator. This
|
|
lets you use middleware functionality on a per-view basis.
|
|
"""
|
|
def _decorator_from_middleware(*args, **kwargs):
|
|
# For historical reasons, these "decorators" are also called as
|
|
# dec(func, *args) instead of dec(*args)(func). We handle both forms
|
|
# for backwards compatibility.
|
|
has_func = True
|
|
try:
|
|
view_func = kwargs.pop('view_func')
|
|
except KeyError:
|
|
if len(args):
|
|
view_func, args = args[0], args[1:]
|
|
else:
|
|
has_func = False
|
|
if not (has_func and isinstance(view_func, types.FunctionType)):
|
|
# We are being called as a decorator.
|
|
if has_func:
|
|
args = (view_func,) + args
|
|
middleware = middleware_class(*args, **kwargs)
|
|
|
|
def decorator_func(fn):
|
|
return _decorator_from_middleware(fn, *args, **kwargs)
|
|
return decorator_func
|
|
|
|
middleware = middleware_class(*args, **kwargs)
|
|
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
if hasattr(middleware, 'process_request'):
|
|
result = middleware.process_request(request)
|
|
if result is not None:
|
|
return result
|
|
if hasattr(middleware, 'process_view'):
|
|
result = middleware.process_view(request, view_func, *args, **kwargs)
|
|
if result is not None:
|
|
return result
|
|
try:
|
|
response = view_func(request, *args, **kwargs)
|
|
except Exception, e:
|
|
if hasattr(middleware, 'process_exception'):
|
|
result = middleware.process_exception(request, e)
|
|
if result is not None:
|
|
return result
|
|
raise
|
|
if hasattr(middleware, 'process_response'):
|
|
result = middleware.process_response(request, response)
|
|
if result is not None:
|
|
return result
|
|
return response
|
|
return wraps(view_func)(_wrapped_view)
|
|
return _decorator_from_middleware
|