app/django/utils/decorators.py
author Sverre Rabbelier <srabbelier@gmail.com>
Sat, 07 Mar 2009 18:16:54 +0000
changeset 1721 9acf4fe1b9bb
parent 54 03e267d67478
permissions -rw-r--r--
Adjust the total_popularity after ranging This way 'off the scale' orgs (many applicants, with only few mentors available) will not pull the total amount of allocated slots down as much as before. 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