Ticket #730: explicit_middleware_ordering_t730_r8166_v2.diff

File explicit_middleware_ordering_t730_r8166_v2.diff, 4.6 KB (added by Andrew Badr, 16 years ago)
  • django/core/handlers/base.py

     
    1717    def __init__(self):
    1818        self._request_middleware = self._view_middleware = self._response_middleware = self._exception_middleware = None
    1919
     20    def middleware_class_from_path(middleware_path):
     21        from django.core import exceptions
     22        try:
     23            dot = middleware_path.rindex('.')
     24        except ValueError:
     25            raise exceptions.ImproperlyConfigured, '%s isn\'t a middleware module' % middleware_path
     26        mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
     27        try:
     28            mod = __import__(mw_module, {}, {}, [''])
     29        except ImportError, e:
     30            raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
     31        try:
     32            mw_class = getattr(mod, mw_classname)
     33        except AttributeError:
     34            raise exceptions.ImproperlyConfigured, 'Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname)
     35        return mw_class
     36    middleware_class_from_path = staticmethod(middleware_class_from_path)
     37
     38
    2039    def load_middleware(self):
    2140        """
    2241        Populate middleware lists from settings.MIDDLEWARE_CLASSES.
     
    2948        self._view_middleware = []
    3049        self._response_middleware = []
    3150        self._exception_middleware = []
    32         for middleware_path in settings.MIDDLEWARE_CLASSES:
    33             try:
    34                 dot = middleware_path.rindex('.')
    35             except ValueError:
    36                 raise exceptions.ImproperlyConfigured, '%s isn\'t a middleware module' % middleware_path
    37             mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
    38             try:
    39                 mod = __import__(mw_module, {}, {}, [''])
    40             except ImportError, e:
    41                 raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
    42             try:
    43                 mw_class = getattr(mod, mw_classname)
    44             except AttributeError:
    45                 raise exceptions.ImproperlyConfigured, 'Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname)
     51       
    4652
     53        # Get incoming and outgoing middleware orders and make sure they contain the same paths
     54        incoming_middleware_order = settings.MIDDLEWARE_CLASSES
     55        outgoing_middleware_order = getattr(settings, 'OUTBOUND_MIDDLEWARE_ORDER', None)
     56        if outgoing_middleware_order:
     57            if not len(incoming_middleware_order) == len(outgoing_middleware_order):
     58                raise exceptions.ImproperlyConfigured, 'OUTBOUND_MIDDLEWARE_ORDER must contain the same middleware as MIDDLEWARE_CLASSES'
     59            for middleware_path in incoming_middleware_order:
     60                if not middleware_path in outgoing_middleware_order:
     61                    raise exceptions.ImproperlyConfigured, 'OUTBOUND_MIDDLEWARE_ORDER does not contain %s MIDDLEWARE_CLASSES' % middleware_path
     62        else:
     63            outgoing_middleware_order = list(incoming_middleware_order)
     64            outgoing_middleware_order.reverse()
     65       
     66        instances = {}
     67        for middleware_path in incoming_middleware_order:
     68            mw_class = self.middleware_class_from_path(middleware_path)
    4769            try:
    4870                mw_instance = mw_class()
    4971            except exceptions.MiddlewareNotUsed:
    5072                continue
    51 
     73            instances[middleware_path] = mw_instance
    5274            if hasattr(mw_instance, 'process_request'):
    5375                self._request_middleware.append(mw_instance.process_request)
    5476            if hasattr(mw_instance, 'process_view'):
    5577                self._view_middleware.append(mw_instance.process_view)
     78               
     79        for middleware_path in outgoing_middleware_order:
     80            if not middleware_path in instances: # If it MiddlewareNotUsed
     81                continue
     82            mw_instance = instances[middleware_path]
    5683            if hasattr(mw_instance, 'process_response'):
    57                 self._response_middleware.insert(0, mw_instance.process_response)
     84                self._response_middleware.append(mw_instance.process_response)
    5885            if hasattr(mw_instance, 'process_exception'):
    59                 self._exception_middleware.insert(0, mw_instance.process_exception)
     86                self._exception_middleware.append(mw_instance.process_exception)
    6087
    6188    def get_response(self, request):
    6289        "Returns an HttpResponse object for the given HttpRequest"
Back to Top