Ticket #730: explicit_middleware_ordering_t730_r8166.diff

File explicit_middleware_ordering_t730_r8166.diff, 4.7 KB (added by andrewbadr, 7 years ago)
  • django/core/handlers/base.py

     
    1 import sys
     1import sys, copy
    22
    33from django import http
    44from django.core import signals
     
    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       
     52        # Get incoming and outgoing middleware orders and make sure they contain the same paths
     53        incoming_middleware_order = settings.MIDDLEWARE_CLASSES
     54        if hasattr(settings, 'OUTGOING_MIDDLEWARE_ORDER'):
     55            outgoing_middleware_order = settings.OUTGOING_MIDDLEWARE_ORDER
     56            if not len(incoming_middleware_order) == len(outgoing_middleware_order):
     57                raise exceptions.ImproperlyConfigured, 'OUTGOING_MIDDLEWARE_ORDER must contain the same middleware as MIDDLEWARE_CLASSES'
     58            for middleware_path in incoming_middleware_order:
     59                if not middleware_path in outgoing_middleware_order:
     60                    raise exceptions.ImproperlyConfigured, 'OUTGOING_MIDDLEWARE_ORDER does not contain %s MIDDLEWARE_CLASSES' % middleware_path
     61        else:
     62            outgoing_middleware_order = copy.copy(incoming_middleware_order)
     63            outgoing_middleware_order.reverse()
     64       
     65        for middleware_path in incoming_middleware_order:
     66            mw_class = self.middleware_class_from_path(middleware_path)
    4667
    4768            try:
    4869                mw_instance = mw_class()
    4970            except exceptions.MiddlewareNotUsed:
    5071                continue
    51 
     72       
    5273            if hasattr(mw_instance, 'process_request'):
    5374                self._request_middleware.append(mw_instance.process_request)
    5475            if hasattr(mw_instance, 'process_view'):
    5576                self._view_middleware.append(mw_instance.process_view)
     77               
     78        for middleware_path in outgoing_middleware_order:
     79
     80            mw_class = self.middleware_class_from_path(middleware_path)
     81
     82            try:
     83                mw_instance = mw_class()
     84            except exceptions.MiddlewareNotUsed:
     85                continue
     86         
    5687            if hasattr(mw_instance, 'process_response'):
    57                 self._response_middleware.insert(0, mw_instance.process_response)
     88                self._response_middleware.append(mw_instance.process_response)
    5889            if hasattr(mw_instance, 'process_exception'):
    59                 self._exception_middleware.insert(0, mw_instance.process_exception)
     90                self._exception_middleware.append(mw_instance.process_exception)
    6091
    6192    def get_response(self, request):
    6293        "Returns an HttpResponse object for the given HttpRequest"
Back to Top