app/django/utils/decorators.py
author Sverre Rabbelier <srabbelier@gmail.com>
Fri, 30 Jan 2009 22:01:27 +0000
changeset 1095 0122dc66e5d2
parent 54 03e267d67478
permissions -rw-r--r--
Add access control to document model and view The access checks are not yet written, but at least the model is stable from now on. Also converted the document view to dynaform while at it. Patch by: Sverre Rabbelier

"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