Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

#22477 Fix Incompatible Global Settings #2591

Closed
wants to merge 3 commits into from

2 participants

@mlavin

Trac Issue: https://code.djangoproject.com/ticket/22477

This changes the value of MIDDLEWARE_CLASSES in the global settings to be in line with the default INSTALLED_APPS setting. While it is not fully backwards compatible it is unlikely to impact most users since MIDDLEWARE_CLASSES is overridden by the startproject command. A compatibility check has been added to warn users which have not set MIDDLEWARE_CLASSES and rely on the defaults.

I've kept the original commits but if accepted I'm happy to squash them into one. Since this problem is exposed by the app-loading refactor I've submitted the PR against the 1.7.x branch. If that's a problem I'm happy to resubmit against master and move the docs and compatibility check forward to 1.8.

@timgraham timgraham commented on the diff
django/conf/global_settings.py
@@ -461,12 +461,7 @@
# response phase the middleware will be applied in reverse order.
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
@timgraham Owner

should we also remove the contrib references in TEMPLATE_CONTEXT_PROCESSORS?

@mlavin
mlavin added a note

I think that's a good idea but it's far more disruptive of a change. UnlikeMIDDLEWARE_CLASSES startproject doesn't define TEMPLATE_CONTEXT_PROCESSORS by default. Many project likely override the setting to add django.core.context_processors.request but it is far more likely for projects to rely on the defaults.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@timgraham timgraham commented on the diff
django/core/checks/compatibility/django_1_7_0.py
((17 lines not shown))
+ warns them about the global default changes.
+ """
+ from django.conf import settings
+
+ # MIDDLEWARE_CLASSES is overridden by default by startproject. If user's 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."
+ "See https://docs.djangoproject.com/en/dev/releases/1.7/ "
@timgraham Owner

I wonder if this link is really needed. If so, it should at least link to a specific section of the release notes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@timgraham timgraham commented on the diff
docs/releases/1.7.txt
@@ -1110,6 +1110,22 @@ in a test class which is a subclass of
:class:`~django.test.TransactionTestCase` rather than
:class:`~django.test.TestCase`.
+Default ``MIDDLEWARE_CLASSES``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@timgraham Owner

underline should be the same length as the text above it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@timgraham timgraham commented on the diff
docs/releases/1.7.txt
@@ -1110,6 +1110,22 @@ in a test class which is a subclass of
:class:`~django.test.TransactionTestCase` rather than
:class:`~django.test.TestCase`.
+Default ``MIDDLEWARE_CLASSES``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The app-loading refactor deprecated using models from apps which are not part
+of the :setting:`INSTALLED_APPS` setting. This left an incompatiblity between
+the default :setting:`INSTALLED_APPS` and :setting:`MIDDLEWARE_CLASSES` in the
+global defaults. To bring these settings insync,
@timgraham Owner

"in sync" (two words)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@timgraham timgraham commented on the diff
django/core/checks/compatibility/django_1_7_0.py
@@ -0,0 +1,39 @@
+# -*- encoding: utf-8 -*-
+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):
@timgraham Owner

Add a test for this check?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@timgraham timgraham commented on the diff
django/core/checks/compatibility/django_1_7_0.py
((6 lines not shown))
+
+@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 user's have removed
@timgraham Owner

users (no apostrophe)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@timgraham
Owner

Please squash the commits and send a PR against master as noted in the ticket, thanks!

@timgraham timgraham closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
5 django/conf/global_settings.py
@@ -461,12 +461,7 @@
# response phase the middleware will be applied in reverse order.
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
@timgraham Owner

should we also remove the contrib references in TEMPLATE_CONTEXT_PROCESSORS?

@mlavin
mlavin added a note

I think that's a good idea but it's far more disruptive of a change. UnlikeMIDDLEWARE_CLASSES startproject doesn't define TEMPLATE_CONTEXT_PROCESSORS by default. Many project likely override the setting to add django.core.context_processors.request but it is far more likely for projects to rely on the defaults.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',
- # 'django.middleware.http.ConditionalGetMiddleware',
- # 'django.middleware.gzip.GZipMiddleware',
)
############
View
18 django/contrib/auth/tests/test_context_processors.py
@@ -77,8 +77,13 @@ class AuthContextProcessorTests(TestCase):
fixtures = ['context-processors-users.xml']
@override_settings(
- MIDDLEWARE_CLASSES=global_settings.MIDDLEWARE_CLASSES,
- TEMPLATE_CONTEXT_PROCESSORS=global_settings.TEMPLATE_CONTEXT_PROCESSORS,
+ MIDDLEWARE_CLASSES=(
+ '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):
"""
@@ -89,8 +94,13 @@ def test_session_not_accessed(self):
self.assertContains(response, "Session not accessed")
@override_settings(
- MIDDLEWARE_CLASSES=global_settings.MIDDLEWARE_CLASSES,
- TEMPLATE_CONTEXT_PROCESSORS=global_settings.TEMPLATE_CONTEXT_PROCESSORS,
+ MIDDLEWARE_CLASSES=(
+ '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):
"""
View
1  django/core/checks/__init__.py
@@ -8,6 +8,7 @@
# Import these to force registration of checks
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
__all__ = [
View
39 django/core/checks/compatibility/django_1_7_0.py
@@ -0,0 +1,39 @@
+# -*- encoding: utf-8 -*-
+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):
@timgraham Owner

Add a test for this check?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ """
+ 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 user's have removed
@timgraham Owner

users (no apostrophe)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ # 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."
+ "See https://docs.djangoproject.com/en/dev/releases/1.7/ "
@timgraham Owner

I wonder if this link is really needed. If so, it should at least link to a specific section of the release notes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ "for more information."),
+ obj=None,
+ id='1_7.W001',
+ )
+ ]
+ else:
+ return []
View
12 docs/ref/settings.txt
@@ -1746,13 +1746,17 @@ MIDDLEWARE_CLASSES
Default::
('django.middleware.common.CommonMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',)
+ 'django.middleware.csrf.CsrfViewMiddleware',)
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
MIGRATION_MODULES
View
16 docs/releases/1.7.txt
@@ -1110,6 +1110,22 @@ in a test class which is a subclass of
:class:`~django.test.TransactionTestCase` rather than
:class:`~django.test.TestCase`.
+Default ``MIDDLEWARE_CLASSES``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@timgraham Owner

underline should be the same length as the text above it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+The app-loading refactor deprecated using models from apps which are not part
+of the :setting:`INSTALLED_APPS` setting. This left an incompatiblity between
+the default :setting:`INSTALLED_APPS` and :setting:`MIDDLEWARE_CLASSES` in the
+global defaults. To bring these settings insync,
@timgraham Owner

"in sync" (two words)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+:class:`~django.contrib.sessions.middleware.SessionMiddleware`,
+:class:`~django.contrib.auth.middleware.AuthenticationMiddleware`, and
+:class:`~django.contrib.messages.middleware.MessageMiddleware` were removed from the defaults.
+While these were removed from the global 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 needs.
+
Miscellaneous
~~~~~~~~~~~~~
View
3  tests/admin_scripts/tests.py
@@ -58,11 +58,12 @@ def write_settings(self, filename, apps=None, is_dir=False, sdict=None, extra=No
'ROOT_URLCONF',
'SECRET_KEY',
'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:
if hasattr(settings, s):
o = getattr(settings, s)
- if not isinstance(o, dict):
+ if not isinstance(o, (dict, tuple, list)):
o = "'%s'" % o
settings_file.write("%s = %s\n" % (s, o))
View
12 tests/runtests.py
@@ -56,6 +56,14 @@
'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():
from django.contrib.gis.tests.utils import HAS_SPATIAL_DB
@@ -107,6 +115,7 @@ def no_available_apps(self):
'LANGUAGE_CODE': settings.LANGUAGE_CODE,
'STATIC_URL': settings.STATIC_URL,
'STATIC_ROOT': settings.STATIC_ROOT,
+ 'MIDDLEWARE_CLASSES': settings.MIDDLEWARE_CLASSES,
}
# Redirect some settings for the duration of these tests.
@@ -117,6 +126,9 @@ def no_available_apps(self):
settings.TEMPLATE_DIRS = (os.path.join(RUNTESTS_DIR, TEST_TEMPLATE_DIR),)
settings.LANGUAGE_CODE = 'en'
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:
# Ensure any warnings captured to logging are piped through a verbose
Something went wrong with that request. Please try again.