Django

Code

Ticket #730: explicit_middleware_ordering_t730_r8166_v2.diff

File explicit_middleware_ordering_t730_r8166_v2.diff, 4.6 kB (added by andrewbadr, 2 years ago)
  • django/core/handlers/base.py

    old new  
    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"