diff --git a/django/core/checks/__init__.py b/django/core/checks/__init__.py index 2502450cdf..34ed710fc1 100644 --- a/django/core/checks/__init__.py +++ b/django/core/checks/__init__.py @@ -24,6 +24,7 @@ import django.core.checks.model_checks # NOQA isort:skip import django.core.checks.security.base # NOQA isort:skip import django.core.checks.security.csrf # NOQA isort:skip import django.core.checks.security.sessions # NOQA isort:skip +import django.core.checks.settings # NOQA isort:skip import django.core.checks.templates # NOQA isort:skip import django.core.checks.translation # NOQA isort:skip import django.core.checks.urls # NOQA isort:skip diff --git a/django/core/checks/registry.py b/django/core/checks/registry.py index 3139fc3ef4..fd35040908 100644 --- a/django/core/checks/registry.py +++ b/django/core/checks/registry.py @@ -18,6 +18,7 @@ class Tags: files = "files" models = "models" security = "security" + settings = "settings" signals = "signals" sites = "sites" staticfiles = "staticfiles" diff --git a/django/core/checks/settings.py b/django/core/checks/settings.py new file mode 100644 index 0000000000..f9111303cc --- /dev/null +++ b/django/core/checks/settings.py @@ -0,0 +1,123 @@ +from django.conf import settings + +from . import Tags, Warning, register + +REMOVED_SETTINGS = { + # Django 1.0 + # https://docs.djangoproject.com/en/stable/releases/1.0/ + # Django 1.1 + # https://docs.djangoproject.com/en/stable/releases/1.1/#features-deprecated-in-1-1 + # Django 1.2 + # https://docs.djangoproject.com/en/stable/releases/1.2/#features-deprecated-in-1-2 + "DATABASE_ENGINE", + "DATABASE_HOST", + "DATABASE_NAME", + "DATABASE_OPTIONS", + "DATABASE_PASSWORD", + "DATABASE_PORT", + "DATABASE_USER", + "TEST_DATABASE_CHARSET", + "TEST_DATABASE_COLLATION", + "TEST_DATABASE_NAME", + # Django 1.3 + # https://docs.djangoproject.com/en/stable/releases/1.3/#features-deprecated-in-1-3 + # Django 1.4 + # https://docs.djangoproject.com/en/stable/releases/1.4/#features-deprecated-in-1-4 + "TRANSACTIONS_MANAGED", + # Django 1.5 + # https://docs.djangoproject.com/en/stable/releases/1.5/#features-deprecated-in-1-5 + "AUTH_PROFILE_MODULE", + # Django 1.7 + # https://docs.djangoproject.com/en/stable/releases/1.7/#features-removed-in-1-7 + "SOUTH_DATABASE_ADAPTER", + "SOUTH_DATABASE_ADAPTERS", + "SOUTH_AUTO_FREEZE_APP", + "SOUTH_TESTS_MIGRATE", + "SOUTH_LOGGING_ON", + "SOUTH_LOGGING_FILE", + "SOUTH_MIGRATION_MODULES", + "SOUTH_USE_PYC", + "TEST_CREATE", + "TEST_USER_CREATE", + "TEST_PASSWD", + "TEST_DATABASE_ENGINE", + "TEST_DATABASE_HOST", + "TEST_DATABASE_NAME", + "TEST_DATABASE_OPTIONS", + "TEST_DATABASE_PASSWORD", + "TEST_DATABASE_PORT", + "TEST_DATABASE_USER", + # Django 1.8 + # https://docs.djangoproject.com/en/stable/releases/1.8/#features-removed-in-1-8 + "SEND_BROKEN_LINK_EMAILS", + "CACHE_MIDDLEWARE_ANONYMOUS_ONLY", + # Django 1.9 + # https://docs.djangoproject.com/en/stable/releases/1.9/#features-removed-in-1-9 + # Django 1.10 + # https://docs.djangoproject.com/en/stable/releases/1.10/#features-removed-in-1-10 + "ALLOWED_INCLUDE_ROOTS", + "LOGOUT_URL", + "TEMPLATE_CONTEXT_PROCESSORS", + "TEMPLATE_DEBUG", + "TEMPLATE_DIRS", + "TEMPLATE_LOADERS", + "TEMPLATE_STRING_IF_INVALID", + # Django 2.0 + # https://docs.djangoproject.com/en/stable/releases/2.0/#features-removed-in-2-0 + "MIDDLEWARE_CLASSES", + # Django 2.1 + # https://docs.djangoproject.com/en/stable/releases/2.1/#features-removed-in-2-1 + "USE_ETAGS", + "SECURE_BROWSER_XSS_FILTER", + # Django 3.0 + # https://docs.djangoproject.com/en/stable/releases/3.0/#features-removed-in-3-0 + "DEFAULT_CONTENT_TYPE", + "PASSWORD_RESET_TIMEOUT_DAYS", + # Django 3.1 + # https://docs.djangoproject.com/en/stable/releases/3.1/#features-removed-in-3-1 + "DEFAULT_FILE_STORAGE", + "FILE_CHARSET", + # Django 4.0 + # https://docs.djangoproject.com/en/stable/releases/4.0/#features-removed-in-4-0 + "DEFAULT_HASHING_ALGORITHM", + "PASSWORD_RESET_TIMEOUT_DAYS", + "SECURE_BROWSER_XSS_FILTER", + # Django 4.1 + # https://docs.djangoproject.com/en/stable/releases/4.1/#features-removed-in-4-1 + # Django 5.0 + # https://docs.djangoproject.com/en/stable/releases/5.0/#features-removed-in-5-0 + "USE_L10N", + "USE_DEPRECATED_PYTZ", + "CSRF_COOKIE_MASKED", + "DATABASE_OPTIONS", + # Django 5.1 + # https://docs.djangoproject.com/en/stable/releases/5.1/#features-removed-in-5-1 + "DEFAULT_FILE_STORAGE", + "STATICFILES_STORAGE", + # Django 6.0 + # RemovedInDjango60Warning: when the deprecation ends, replace with: + # "FORMS_URLFIELD_ASSUME_HTTPS", +} + + +@register(Tags.settings) +def check_removed_settings(**kwargs): + """ + This check warns users who still use deprecated settings variables. + """ + + warnings = [] + for setting_name in dir(settings): + if setting_name.isupper() and setting_name in REMOVED_SETTINGS: + warnings.append( + Warning( + f"The {setting_name!r} setting was removed and its use is " + f"not recommended.", + hint="Please refer to the documentation and remove/replace " + "this setting.", + obj=setting_name, + id="settings.W001", + ) + ) + + return warnings diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 2308a854c7..1b53e0bef1 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -120,6 +120,12 @@ upgrading Django. :setting:`CSRF_TRUSTED_ORIGINS` setting must start with a scheme (usually ``http://`` or ``https://``) but found ````. +Removed setting variables +------------------------- + +* **settings.W001**: The ```` setting was removed and its use is not + recommended. + Caches ------ diff --git a/docs/releases/5.2.txt b/docs/releases/5.2.txt index 9090f8b70a..b7dbd909ae 100644 --- a/docs/releases/5.2.txt +++ b/docs/releases/5.2.txt @@ -291,6 +291,13 @@ Signals * ... +System checks +~~~~~~~~~~~~~ + +* Added a new system check for detecting removed Django setting variables. + This check will point out all usages of known removals starting from + Django v1.0 and will raise a **settings.W001** warning. + Templates ~~~~~~~~~ diff --git a/tests/check_framework/test_settings.py b/tests/check_framework/test_settings.py new file mode 100644 index 0000000000..6d479ae78f --- /dev/null +++ b/tests/check_framework/test_settings.py @@ -0,0 +1,23 @@ +from django.apps import apps +from django.core import checks +from django.test import SimpleTestCase, override_settings + + +class RemovedSettingsCheckTests(SimpleTestCase): + @override_settings(TRANSACTIONS_MANAGED=True) + def test_check_removed_settings(self): + all_issues = checks.run_checks(app_configs=apps.get_app_configs()) + + self.assertGreater(len(all_issues), 0) + + self.assertIn( + checks.Warning( + "The 'TRANSACTIONS_MANAGED' setting was removed and its use " + "is not recommended.", + hint="Please refer to the documentation and remove/replace " + "this setting.", + obj="TRANSACTIONS_MANAGED", + id="settings.W001", + ), + all_issues, + )