summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodrigo <matematica.a3k@gmail.com>2018-08-20 18:57:46 -0300
committerTim Graham <timograham@gmail.com>2018-08-20 17:57:46 -0400
commit371ece2f0682e51f2f796854d3e091827a7cea63 (patch)
tree6eff7fc6db3fad32df956011a5fd657469ed534c
parentac29fec1116953a70f055c45a0aef6a24477653e (diff)
Fixed #29695 -- Added system checks for admin's app dependencies and TEMPLATES setting.
-rw-r--r--django/contrib/admin/checks.py91
-rw-r--r--docs/ref/checks.txt21
-rw-r--r--tests/admin_checks/tests.py87
-rw-r--r--tests/admin_scripts/tests.py21
4 files changed, 182 insertions, 38 deletions
diff --git a/django/contrib/admin/checks.py b/django/contrib/admin/checks.py
index fbc8d50693..d129acb124 100644
--- a/django/contrib/admin/checks.py
+++ b/django/contrib/admin/checks.py
@@ -14,7 +14,8 @@ from django.db.models.expressions import Combinable, F, OrderBy
from django.forms.models import (
BaseModelForm, BaseModelFormSet, _get_foreign_key,
)
-from django.template.engine import Engine
+from django.template import engines
+from django.template.backends.django import DjangoTemplates
from django.utils.deprecation import RemovedInDjango30Warning
from django.utils.inspect import get_func_args
@@ -31,38 +32,68 @@ def check_dependencies(**kwargs):
"""
Check that the admin's dependencies are correctly installed.
"""
+ if not apps.is_installed('django.contrib.admin'):
+ return []
errors = []
- # contrib.contenttypes must be installed.
- if not apps.is_installed('django.contrib.contenttypes'):
- missing_app = checks.Error(
- "'django.contrib.contenttypes' must be in INSTALLED_APPS in order "
- "to use the admin application.",
- id="admin.E401",
- )
- errors.append(missing_app)
- # The auth context processor must be installed if using the default
- # authentication backend.
- try:
- default_template_engine = Engine.get_default()
- except Exception:
- # Skip this non-critical check:
- # 1. if the user has a non-trivial TEMPLATES setting and Django
- # can't find a default template engine
- # 2. if anything goes wrong while loading template engines, in
- # order to avoid raising an exception from a confusing location
- # Catching ImproperlyConfigured suffices for 1. but 2. requires
- # catching all exceptions.
- pass
+ app_dependencies = (
+ ('django.contrib.contenttypes', 401),
+ ('django.contrib.auth', 405),
+ ('django.contrib.messages', 406),
+ ('django.contrib.sessions', 407),
+ )
+ for app_name, error_code in app_dependencies:
+ if not apps.is_installed(app_name):
+ errors.append(checks.Error(
+ "'%s' must be in INSTALLED_APPS in order to use the admin "
+ "application." % app_name,
+ id='admin.E%d' % error_code,
+ ))
+ for engine in engines.all():
+ if isinstance(engine, DjangoTemplates):
+ django_templates_instance = engine.engine
+ break
+ else:
+ django_templates_instance = None
+ if not django_templates_instance:
+ errors.append(checks.Error(
+ "A 'django.template.backends.django.DjangoTemplates' instance "
+ "must be configured in TEMPLATES in order to use the admin "
+ "application.",
+ id='admin.E403',
+ ))
else:
if ('django.contrib.auth.context_processors.auth'
- not in default_template_engine.context_processors and
- 'django.contrib.auth.backends.ModelBackend' in settings.AUTHENTICATION_BACKENDS):
- missing_template = checks.Error(
- "'django.contrib.auth.context_processors.auth' must be in "
- "TEMPLATES in order to use the admin application.",
- id="admin.E402"
- )
- errors.append(missing_template)
+ not in django_templates_instance.context_processors and
+ 'django.contrib.auth.backends.ModelBackend'
+ in settings.AUTHENTICATION_BACKENDS):
+ errors.append(checks.Error(
+ "'django.contrib.auth.context_processors.auth' must be "
+ "enabled in DjangoTemplates (TEMPLATES) if using the default "
+ "auth backend in order to use the admin application.",
+ id='admin.E402',
+ ))
+ if ('django.contrib.messages.context_processors.messages'
+ not in django_templates_instance.context_processors):
+ errors.append(checks.Error(
+ "'django.contrib.messages.context_processors.messages' must "
+ "be enabled in DjangoTemplates (TEMPLATES) in order to use "
+ "the admin application.",
+ id='admin.E404',
+ ))
+ if ('django.contrib.auth.middleware.AuthenticationMiddleware'
+ not in settings.MIDDLEWARE):
+ errors.append(checks.Error(
+ "'django.contrib.auth.middleware.AuthenticationMiddleware' must "
+ "be in MIDDLEWARE in order to use the admin application.",
+ id='admin.E408',
+ ))
+ if ('django.contrib.messages.middleware.MessageMiddleware'
+ not in settings.MIDDLEWARE):
+ errors.append(checks.Error(
+ "'django.contrib.messages.middleware.MessageMiddleware' must "
+ "be in MIDDLEWARE in order to use the admin application.",
+ id='admin.E409',
+ ))
return errors
diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt
index ee16ebde54..a84d9b60b6 100644
--- a/docs/ref/checks.txt
+++ b/docs/ref/checks.txt
@@ -624,7 +624,26 @@ The following checks are performed on the default
* **admin.E401**: :mod:`django.contrib.contenttypes` must be in
:setting:`INSTALLED_APPS` in order to use the admin application.
* **admin.E402**: :mod:`django.contrib.auth.context_processors.auth`
- must be in :setting:`TEMPLATES` in order to use the admin application.
+ must be enabled in :class:`~django.template.backends.django.DjangoTemplates`
+ (:setting:`TEMPLATES`) if using the default auth backend in order to use the
+ admin application.
+* **admin.E403**: A :class:`django.template.backends.django.DjangoTemplates`
+ instance must be configured in :setting:`TEMPLATES` in order to use the
+ admin application.
+* **admin.E404**: ``django.contrib.messages.context_processors.messages``
+ must be enabled in :class:`~django.template.backends.django.DjangoTemplates`
+ (:setting:`TEMPLATES`) in order to use the admin application.
+* **admin.E405**: :mod:`django.contrib.auth` must be in
+ :setting:`INSTALLED_APPS` in order to use the admin application.
+* **admin.E406**: :mod:`django.contrib.messages` must be in
+ :setting:`INSTALLED_APPS` in order to use the admin application.
+* **admin.E407**: :mod:`django.contrib.sessions` must be in
+ :setting:`INSTALLED_APPS` in order to use the admin application.
+* **admin.E408**:
+ :class:`django.contrib.auth.middleware.AuthenticationMiddleware` must be in
+ :setting:`MIDDLEWARE` in order to use the admin application.
+* **admin.E409**: :class:`django.contrib.messages.middleware.MessageMiddleware`
+ must be in :setting:`MIDDLEWARE` in order to use the admin application.
``auth``
--------
diff --git a/tests/admin_checks/tests.py b/tests/admin_checks/tests.py
index a968cd5ba3..d5661a137d 100644
--- a/tests/admin_checks/tests.py
+++ b/tests/admin_checks/tests.py
@@ -43,6 +43,8 @@ class MyAdmin(admin.ModelAdmin):
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
'admin_checks',
],
)
@@ -58,20 +60,42 @@ class SystemChecksTestCase(SimpleTestCase):
admin.site.unregister(Song)
@override_settings(INSTALLED_APPS=['django.contrib.admin'])
- def test_contenttypes_dependency(self):
+ def test_apps_dependencies(self):
errors = admin.checks.check_dependencies()
expected = [
checks.Error(
"'django.contrib.contenttypes' must be in "
"INSTALLED_APPS in order to use the admin application.",
id="admin.E401",
+ ),
+ checks.Error(
+ "'django.contrib.auth' must be in INSTALLED_APPS in order "
+ "to use the admin application.",
+ id='admin.E405',
+ ),
+ checks.Error(
+ "'django.contrib.messages' must be in INSTALLED_APPS in order "
+ "to use the admin application.",
+ id='admin.E406',
+ ),
+ checks.Error(
+ "'django.contrib.sessions' must be in INSTALLED_APPS in order "
+ "to use the admin application.",
+ id='admin.E407',
)
]
self.assertEqual(errors, expected)
@override_settings(TEMPLATES=[])
def test_no_template_engines(self):
- self.assertEqual(admin.checks.check_dependencies(), [])
+ self.assertEqual(admin.checks.check_dependencies(), [
+ checks.Error(
+ "A 'django.template.backends.django.DjangoTemplates' "
+ "instance must be configured in TEMPLATES in order to use "
+ "the admin application.",
+ id='admin.E403',
+ )
+ ])
@override_settings(
TEMPLATES=[{
@@ -83,13 +107,64 @@ class SystemChecksTestCase(SimpleTestCase):
},
}],
)
- def test_auth_contextprocessor_dependency(self):
+ def test_context_processor_dependencies(self):
+ expected = [
+ checks.Error(
+ "'django.contrib.auth.context_processors.auth' must be "
+ "enabled in DjangoTemplates (TEMPLATES) if using the default "
+ "auth backend in order to use the admin application.",
+ id='admin.E402',
+ ),
+ checks.Error(
+ "'django.contrib.messages.context_processors.messages' must "
+ "be enabled in DjangoTemplates (TEMPLATES) in order to use "
+ "the admin application.",
+ id='admin.E404',
+ )
+ ]
+ self.assertEqual(admin.checks.check_dependencies(), expected)
+ # The first error doesn't happen if
+ # 'django.contrib.auth.backends.ModelBackend' isn't in
+ # AUTHENTICATION_BACKENDS.
+ with self.settings(AUTHENTICATION_BACKENDS=[]):
+ self.assertEqual(admin.checks.check_dependencies(), expected[1:])
+
+ @override_settings(
+ TEMPLATES=[
+ {
+ 'BACKEND': 'django.template.backends.jinja2.Jinja2',
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ },
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+ ],
+ )
+ def test_several_templates_backends(self):
+ self.assertEqual(admin.checks.check_dependencies(), [])
+
+ @override_settings(MIDDLEWARE=[])
+ def test_middleware_dependencies(self):
errors = admin.checks.check_dependencies()
expected = [
checks.Error(
- "'django.contrib.auth.context_processors.auth' must be in "
- "TEMPLATES in order to use the admin application.",
- id="admin.E402",
+ "'django.contrib.auth.middleware.AuthenticationMiddleware' "
+ "must be in MIDDLEWARE in order to use the admin application.",
+ id='admin.E408',
+ ),
+ checks.Error(
+ "'django.contrib.messages.middleware.MessageMiddleware' "
+ "must be in MIDDLEWARE in order to use the admin application.",
+ id='admin.E409',
)
]
self.assertEqual(errors, expected)
diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py
index c1d8baef6b..c60194fe72 100644
--- a/tests/admin_scripts/tests.py
+++ b/tests/admin_scripts/tests.py
@@ -1172,9 +1172,28 @@ class ManageCheck(AdminScriptTestCase):
'django.contrib.admin.apps.SimpleAdminConfig',
'django.contrib.auth',
'django.contrib.contenttypes',
+ 'django.contrib.messages',
+ 'django.contrib.sessions',
],
sdict={
- 'DEBUG': True
+ 'DEBUG': True,
+ 'MIDDLEWARE': [
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ ],
+ 'TEMPLATES': [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+ ],
}
)
args = ['check']