Django

Code

Ticket #730: explicit_middleware_ordering_t730_r8166.diff

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

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