Fixed #22477 -- Removed contrib middleware from the global settings defaults.

Also added a compatibility check for changed middleware defaults.

Forwardport of d94de802d3 from stable/1.7.x
This commit is contained in:
mlavin 2014-04-20 08:58:29 -04:00 committed by Tim Graham
parent cc35bd461d
commit 4696cd9671
9 changed files with 131 additions and 15 deletions

View File

@ -454,12 +454,7 @@ SECURE_PROXY_SSL_HEADER = None
# response phase the middleware will be applied in reverse order. # response phase the middleware will be applied in reverse order.
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# 'django.middleware.http.ConditionalGetMiddleware',
# 'django.middleware.gzip.GZipMiddleware',
) )
############ ############

View File

@ -1,6 +1,5 @@
import os import os
from django.conf import global_settings
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.contrib.auth.tests.utils import skipIfCustomUser from django.contrib.auth.tests.utils import skipIfCustomUser
from django.contrib.auth.models import User, Permission from django.contrib.auth.models import User, Permission
@ -77,8 +76,13 @@ class AuthContextProcessorTests(TestCase):
fixtures = ['context-processors-users.xml'] fixtures = ['context-processors-users.xml']
@override_settings( @override_settings(
MIDDLEWARE_CLASSES=global_settings.MIDDLEWARE_CLASSES, MIDDLEWARE_CLASSES=(
TEMPLATE_CONTEXT_PROCESSORS=global_settings.TEMPLATE_CONTEXT_PROCESSORS, 'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
),
TEMPLATE_CONTEXT_PROCESSORS=(
'django.contrib.auth.context_processors.auth',
),
) )
def test_session_not_accessed(self): def test_session_not_accessed(self):
""" """
@ -89,8 +93,13 @@ class AuthContextProcessorTests(TestCase):
self.assertContains(response, "Session not accessed") self.assertContains(response, "Session not accessed")
@override_settings( @override_settings(
MIDDLEWARE_CLASSES=global_settings.MIDDLEWARE_CLASSES, MIDDLEWARE_CLASSES=(
TEMPLATE_CONTEXT_PROCESSORS=global_settings.TEMPLATE_CONTEXT_PROCESSORS, 'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
),
TEMPLATE_CONTEXT_PROCESSORS=(
'django.contrib.auth.context_processors.auth',
),
) )
def test_session_is_accessed(self): def test_session_is_accessed(self):
""" """

View File

@ -8,6 +8,7 @@ from .registry import register, run_checks, tag_exists, Tags
# Import these to force registration of checks # Import these to force registration of checks
import django.core.checks.compatibility.django_1_6_0 # NOQA import django.core.checks.compatibility.django_1_6_0 # NOQA
import django.core.checks.compatibility.django_1_7_0 # NOQA
import django.core.checks.model_checks # NOQA import django.core.checks.model_checks # NOQA
__all__ = [ __all__ = [

View File

@ -0,0 +1,36 @@
from __future__ import unicode_literals
from .. import Warning, register, Tags
@register(Tags.compatibility)
def check_1_7_compatibility(**kwargs):
errors = []
errors.extend(_check_middleware_classes(**kwargs))
return errors
def _check_middleware_classes(app_configs=None, **kwargs):
"""
Checks if the user has *not* overridden the ``MIDDLEWARE_CLASSES`` setting &
warns them about the global default changes.
"""
from django.conf import settings
# MIDDLEWARE_CLASSES is overridden by default by startproject. If users
# have removed this override then we'll warn them about the default changes.
if not settings.is_overridden('MIDDLEWARE_CLASSES'):
return [
Warning(
"MIDDLEWARE_CLASSES is not set.",
hint=("Django 1.7 changed the global defaults for the MIDDLEWARE_CLASSES."
"django.contrib.sessions.middleware.SessionMiddleware, "
"django.contrib.auth.middleware.AuthenticationMiddleware, and "
"django.contrib.messages.middleware.MessageMiddleware were removed from the defaults."
"If your project needs these middleware then you should configure this setting."),
obj=None,
id='1_7.W001',
)
]
else:
return []

View File

@ -1734,13 +1734,17 @@ MIDDLEWARE_CLASSES
Default:: Default::
('django.middleware.common.CommonMiddleware', ('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',)
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',)
A tuple of middleware classes to use. See :doc:`/topics/http/middleware`. A tuple of middleware classes to use. See :doc:`/topics/http/middleware`.
.. versionchanged:: 1.7
:class:`~django.contrib.sessions.middleware.SessionMiddleware`,
:class:`~django.contrib.auth.middleware.AuthenticationMiddleware`, and
:class:`~django.contrib.messages.middleware.MessageMiddleware` were removed
from this setting.
.. setting:: MIGRATION_MODULES .. setting:: MIGRATION_MODULES
MIGRATION_MODULES MIGRATION_MODULES

View File

@ -68,6 +68,8 @@ but a few of the key features are:
inside ``TransactionTestCase`` :ref:`unless specifically requested inside ``TransactionTestCase`` :ref:`unless specifically requested
<test-case-serialized-rollback>`. <test-case-serialized-rollback>`.
.. _app-loading-refactor-17-release-note:
App-loading refactor App-loading refactor
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
@ -1114,6 +1116,27 @@ in a test class which is a subclass of
:class:`~django.test.TransactionTestCase` rather than :class:`~django.test.TransactionTestCase` rather than
:class:`~django.test.TestCase`. :class:`~django.test.TestCase`.
Contrib middleware removed from default :setting:`MIDDLEWARE_CLASSES`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The :ref:`app-loading refactor <app-loading-refactor-17-release-note>`
deprecated using models from apps which are not part of the
:setting:`INSTALLED_APPS` setting. This exposed an incompatibility between
the default :setting:`INSTALLED_APPS` and :setting:`MIDDLEWARE_CLASSES` in the
global defaults (``django.conf.global_settings``). To bring these settings in
sync and prevent deprecation warnings when doing things like testing reusable
apps with minimal settings,
:class:`~django.contrib.sessions.middleware.SessionMiddleware`,
:class:`~django.contrib.auth.middleware.AuthenticationMiddleware`, and
:class:`~django.contrib.messages.middleware.MessageMiddleware` were removed
from the defaults. These classes will still be included in the default settings
generated by :djadmin:`startproject`. Most projects will not be affected by
this change but if you were not previously declaring the
:setting:`MIDDLEWARE_CLASSES` in your project settings and relying on the
global default you should ensure that the new defaults are in line with your
project's needs. You should also check for any code that accesses
``django.conf.global_settings.MIDDLEWARE_CLASSES`` directly.
Miscellaneous Miscellaneous
~~~~~~~~~~~~~ ~~~~~~~~~~~~~

View File

@ -58,11 +58,12 @@ class AdminScriptTestCase(unittest.TestCase):
'ROOT_URLCONF', 'ROOT_URLCONF',
'SECRET_KEY', 'SECRET_KEY',
'TEST_RUNNER', # We need to include TEST_RUNNER, otherwise we get a compatibility warning. 'TEST_RUNNER', # We need to include TEST_RUNNER, otherwise we get a compatibility warning.
'MIDDLEWARE_CLASSES', # We need to include MIDDLEWARE_CLASSES, otherwise we get a compatibility warning.
] ]
for s in exports: for s in exports:
if hasattr(settings, s): if hasattr(settings, s):
o = getattr(settings, s) o = getattr(settings, s)
if not isinstance(o, dict): if not isinstance(o, (dict, tuple, list)):
o = "'%s'" % o o = "'%s'" % o
settings_file.write("%s = %s\n" % (s, o)) settings_file.write("%s = %s\n" % (s, o))

View File

@ -10,6 +10,7 @@ from django.core import checks
from django.core.checks import Error, Warning from django.core.checks import Error, Warning
from django.core.checks.registry import CheckRegistry from django.core.checks.registry import CheckRegistry
from django.core.checks.compatibility.django_1_6_0 import check_1_6_compatibility from django.core.checks.compatibility.django_1_6_0 import check_1_6_compatibility
from django.core.checks.compatibility.django_1_7_0 import check_1_7_compatibility
from django.core.management.base import CommandError from django.core.management.base import CommandError
from django.core.management import call_command from django.core.management import call_command
from django.db.models.fields import NOT_PROVIDED from django.db.models.fields import NOT_PROVIDED
@ -148,6 +149,40 @@ class Django_1_6_0_CompatibilityChecks(TestCase):
boolean_field.default = old_default boolean_field.default = old_default
class Django_1_7_0_CompatibilityChecks(TestCase):
@override_settings(MIDDLEWARE_CLASSES=('django.contrib.sessions.middleware.SessionMiddleware',))
def test_middleware_classes_overridden(self):
errors = check_1_7_compatibility()
self.assertEqual(errors, [])
def test_middleware_classes_not_set_explicitly(self):
# If MIDDLEWARE_CLASSES was set explicitly, temporarily pretend it wasn't
middleware_classes_overridden = False
if 'MIDDLEWARE_CLASSES' in settings._wrapped._explicit_settings:
middleware_classes_overridden = True
settings._wrapped._explicit_settings.remove('MIDDLEWARE_CLASSES')
try:
errors = check_1_7_compatibility()
expected = [
checks.Warning(
"MIDDLEWARE_CLASSES is not set.",
hint=("Django 1.7 changed the global defaults for the MIDDLEWARE_CLASSES."
"django.contrib.sessions.middleware.SessionMiddleware, "
"django.contrib.auth.middleware.AuthenticationMiddleware, and "
"django.contrib.messages.middleware.MessageMiddleware were removed from the defaults."
"If your project needs these middleware then you should configure this setting."),
obj=None,
id='1_7.W001',
)
]
self.assertEqual(errors, expected)
finally:
# Restore settings value
if middleware_classes_overridden:
settings._wrapped._explicit_settings.add('MIDDLEWARE_CLASSES')
def simple_system_check(**kwargs): def simple_system_check(**kwargs):
simple_system_check.kwargs = kwargs simple_system_check.kwargs = kwargs
return [] return []

View File

@ -58,6 +58,14 @@ ALWAYS_INSTALLED_APPS = [
'servers.another_app', 'servers.another_app',
] ]
ALWAYS_MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
def get_test_modules(): def get_test_modules():
from django.contrib.gis.tests.utils import HAS_SPATIAL_DB from django.contrib.gis.tests.utils import HAS_SPATIAL_DB
@ -106,6 +114,7 @@ def setup(verbosity, test_labels):
'LANGUAGE_CODE': settings.LANGUAGE_CODE, 'LANGUAGE_CODE': settings.LANGUAGE_CODE,
'STATIC_URL': settings.STATIC_URL, 'STATIC_URL': settings.STATIC_URL,
'STATIC_ROOT': settings.STATIC_ROOT, 'STATIC_ROOT': settings.STATIC_ROOT,
'MIDDLEWARE_CLASSES': settings.MIDDLEWARE_CLASSES,
} }
# Redirect some settings for the duration of these tests. # Redirect some settings for the duration of these tests.
@ -116,6 +125,9 @@ def setup(verbosity, test_labels):
settings.TEMPLATE_DIRS = (os.path.join(RUNTESTS_DIR, TEST_TEMPLATE_DIR),) settings.TEMPLATE_DIRS = (os.path.join(RUNTESTS_DIR, TEST_TEMPLATE_DIR),)
settings.LANGUAGE_CODE = 'en' settings.LANGUAGE_CODE = 'en'
settings.SITE_ID = 1 settings.SITE_ID = 1
settings.MIDDLEWARE_CLASSES = ALWAYS_MIDDLEWARE_CLASSES
# Ensure the middleware classes are seen as overridden otherwise we get a compatibility warning.
settings._explicit_settings.add('MIDDLEWARE_CLASSES')
if verbosity > 0: if verbosity > 0:
# Ensure any warnings captured to logging are piped through a verbose # Ensure any warnings captured to logging are piped through a verbose