Ticket #730: middleware_dict_single_instances_basic_sanity_checks.diff

File middleware_dict_single_instances_basic_sanity_checks.diff, 8.8 KB (added by mrts, 7 years ago)

Improved dict middleware setting. Single instances, basic hasattr('process_foo', mw) checks.

  • django/conf/project_template/settings.py

     
    5757#     'django.template.loaders.eggs.load_template_source',
    5858)
    5959
    60 MIDDLEWARE_CLASSES = (
    61     'django.middleware.common.CommonMiddleware',
    62     'django.contrib.sessions.middleware.SessionMiddleware',
    63     'django.contrib.auth.middleware.AuthenticationMiddleware',
    64     'django.middleware.doc.XViewMiddleware',
    65 )
     60MIDDLEWARE_CLASSES = {
     61    'request': (
     62        'django.middleware.common.CommonMiddleware',
     63        'django.contrib.sessions.middleware.SessionMiddleware',
     64        'django.contrib.auth.middleware.AuthenticationMiddleware',
     65    ),
     66    'response': (
     67        'django.contrib.sessions.middleware.SessionMiddleware',
     68#        'django.middleware.http.ConditionalGetMiddleware',
     69#        'django.middleware.gzip.GZipMiddleware',
     70        'django.middleware.common.CommonMiddleware',
     71    ),
     72    'view': (
     73        'django.middleware.doc.XViewMiddleware',
     74    ),
     75}
    6676
    6777ROOT_URLCONF = '{{ project_name }}.urls'
    6878
  • django/conf/global_settings.py

     
    291291# MIDDLEWARE #
    292292##############
    293293
    294 # List of middleware classes to use.  Order is important; in the request phase,
    295 # this middleware classes will be applied in the order given, and in the
    296 # response phase the middleware will be applied in reverse order.
    297 MIDDLEWARE_CLASSES = (
    298     'django.contrib.sessions.middleware.SessionMiddleware',
    299     'django.contrib.auth.middleware.AuthenticationMiddleware',
    300 #     'django.middleware.http.ConditionalGetMiddleware',
    301 #     'django.middleware.gzip.GZipMiddleware',
    302     'django.middleware.common.CommonMiddleware',
    303     'django.middleware.doc.XViewMiddleware',
    304 )
     294# List of middleware classes to use.  Order is important; all middleware types
     295# will be applied in the order given.
     296MIDDLEWARE_CLASSES = {
     297    'request': (
     298        'django.middleware.common.CommonMiddleware',
     299        'django.contrib.sessions.middleware.SessionMiddleware',
     300        'django.contrib.auth.middleware.AuthenticationMiddleware',
     301    ),
     302    'response': (
     303        'django.contrib.sessions.middleware.SessionMiddleware',
     304#        'django.middleware.http.ConditionalGetMiddleware',
     305#        'django.middleware.gzip.GZipMiddleware',
     306        'django.middleware.common.CommonMiddleware',
     307    ),
     308    'view': (
     309        'django.middleware.doc.XViewMiddleware',
     310    ),
     311}
    305312
    306313############
    307314# SESSIONS #
  • django/core/handlers/base.py

     
    11import sys
    22
    33from django import http
     4from django.core import exceptions
    45from django.core import signals
    56from django.utils.encoding import force_unicode
    67
     
    1617    def __init__(self):
    1718        self._request_middleware = self._view_middleware = self._response_middleware = self._exception_middleware = None
    1819
    19     def load_middleware(self):
    20         """
    21         Populate middleware lists from settings.MIDDLEWARE_CLASSES.
    22 
    23         Must be called after the environment is fixed (see __call__).
    24         """
    25         from django.conf import settings
    26         from django.core import exceptions
     20    def _load_middleware_from_list(self, mw_paths):
    2721        self._request_middleware = []
    2822        self._view_middleware = []
    2923        self._response_middleware = []
    3024        self._exception_middleware = []
    31         for middleware_path in settings.MIDDLEWARE_CLASSES:
    32             try:
    33                 dot = middleware_path.rindex('.')
    34             except ValueError:
    35                 raise exceptions.ImproperlyConfigured, '%s isn\'t a middleware module' % middleware_path
    36             mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
    37             try:
    38                 mod = __import__(mw_module, {}, {}, [''])
    39             except ImportError, e:
    40                 raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
    41             try:
    42                 mw_class = getattr(mod, mw_classname)
    43             except AttributeError:
    44                 raise exceptions.ImproperlyConfigured, 'Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname)
    45 
    46             try:
    47                 mw_instance = mw_class()
    48             except exceptions.MiddlewareNotUsed:
    49                 continue
    50 
     25        mw_instances = [ _middleware_instance_from_path(mw_path) for mw_path
     26                in mw_paths ]
     27        for mw_instance in mw_instances:
    5128            if hasattr(mw_instance, 'process_request'):
    5229                self._request_middleware.append(mw_instance.process_request)
    5330            if hasattr(mw_instance, 'process_view'):
     
    5734            if hasattr(mw_instance, 'process_exception'):
    5835                self._exception_middleware.insert(0, mw_instance.process_exception)
    5936
     37    def _load_middleware_from_dict(self, mw_dict):
     38        # fill the instances dict so that we have only one instance of each
     39        # middleware
     40        mw_instances = {}
     41        for mw_path_tuple in mw_dict.values():
     42            for mw_path in mw_path_tuple:
     43                if mw_path not in mw_instances:
     44                    mw_instances[mw_path] = _middleware_instance_from_path(mw_path)
     45
     46        self._request_middleware = _middleware_type_from_dicts('request',
     47                mw_instances, mw_dict)
     48        self._view_middleware = _middleware_type_from_dicts('view',
     49                mw_instances, mw_dict)
     50        self._response_middleware = _middleware_type_from_dicts('response',
     51                mw_instances, mw_dict)
     52        self._exception_middleware = _middleware_type_from_dicts('exception',
     53                mw_instances, mw_dict)
     54
     55    def load_middleware(self):
     56        """
     57        Populate middleware lists from settings.MIDDLEWARE_CLASSES.
     58
     59        Must be called after the environment is fixed (see __call__).
     60        """
     61        from django.conf import settings
     62        if isinstance(settings.MIDDLEWARE_CLASSES, (tuple, list)):
     63            self._load_middleware_from_list(settings.MIDDLEWARE_CLASSES)
     64        elif isinstance(settings.MIDDLEWARE_CLASSES, (dict)):
     65            self._load_middleware_from_dict(settings.MIDDLEWARE_CLASSES)
     66        else:
     67            raise ImproperlyConfigured("MIDDLEWARE_CLASSES setting has to be"
     68                    "either a tuple, list or a dict.")
     69
    6070    def get_response(self, request):
    6171        "Returns an HttpResponse object for the given HttpRequest"
    62         from django.core import exceptions, urlresolvers
     72        from django.core import urlresolvers
    6373        from django.conf import settings
    6474
    6575        # Apply request middleware
     
    195205        return force_unicode(script_url[:-len(environ.get('PATH_INFO', ''))])
    196206    return force_unicode(environ.get('SCRIPT_NAME', u''))
    197207
     208def _middleware_instance_from_path(middleware_path):
     209    try:
     210        dot = middleware_path.rindex('.')
     211    except ValueError:
     212        raise exceptions.ImproperlyConfigured, '%s isn\'t a middleware module' % middleware_path
     213    mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
     214    try:
     215        mod = __import__(mw_module, {}, {}, [''])
     216    except ImportError, e:
     217        raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
     218    try:
     219        mw_class = getattr(mod, mw_classname)
     220    except AttributeError:
     221        raise exceptions.ImproperlyConfigured, 'Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname)
     222    # I'm ignoring the MiddlewareNotUsed exception as it's not used in Django
     223    # according to grep, not documented and the only use case I can see is to
     224    # raise it in custom middleware __init__ to disable the middleware
     225    # temporarily. That can be better achieved with disabling it in settings
     226    # (where it is explicit and visible). If everybody is happy with that, the
     227    # exception should be removed from core.exceptions. See also #7820.
     228    return mw_class()
     229
     230def _middleware_type_from_dicts(mw_type, mw_instance_dict, mw_dict):
     231    mw_instance_list = []
     232    for mw_path in mw_dict.get(mw_type, []):
     233        mw_instance = mw_instance_dict[mw_path]
     234        if not hasattr(mw_instance, 'process_' + mw_type):
     235            raise ImproperlyConfigured("%s middleware needs a 'process_%s' "
     236                    "method, but it's missing from %s." % (mw_type.title(),
     237                        mw_type, mw_path))
     238        mw_instance_list.append(mw_instance)
     239    return mw_instance_list
Back to Top