mirror of https://github.com/django/django.git
Fixed #29695 -- Added system checks for admin's app dependencies and TEMPLATES setting.
This commit is contained in:
parent
ac29fec111
commit
371ece2f06
|
@ -14,7 +14,8 @@ from django.db.models.expressions import Combinable, F, OrderBy
|
||||||
from django.forms.models import (
|
from django.forms.models import (
|
||||||
BaseModelForm, BaseModelFormSet, _get_foreign_key,
|
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.deprecation import RemovedInDjango30Warning
|
||||||
from django.utils.inspect import get_func_args
|
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.
|
Check that the admin's dependencies are correctly installed.
|
||||||
"""
|
"""
|
||||||
|
if not apps.is_installed('django.contrib.admin'):
|
||||||
|
return []
|
||||||
errors = []
|
errors = []
|
||||||
# contrib.contenttypes must be installed.
|
app_dependencies = (
|
||||||
if not apps.is_installed('django.contrib.contenttypes'):
|
('django.contrib.contenttypes', 401),
|
||||||
missing_app = checks.Error(
|
('django.contrib.auth', 405),
|
||||||
"'django.contrib.contenttypes' must be in INSTALLED_APPS in order "
|
('django.contrib.messages', 406),
|
||||||
"to use the admin application.",
|
('django.contrib.sessions', 407),
|
||||||
id="admin.E401",
|
)
|
||||||
)
|
for app_name, error_code in app_dependencies:
|
||||||
errors.append(missing_app)
|
if not apps.is_installed(app_name):
|
||||||
# The auth context processor must be installed if using the default
|
errors.append(checks.Error(
|
||||||
# authentication backend.
|
"'%s' must be in INSTALLED_APPS in order to use the admin "
|
||||||
try:
|
"application." % app_name,
|
||||||
default_template_engine = Engine.get_default()
|
id='admin.E%d' % error_code,
|
||||||
except Exception:
|
))
|
||||||
# Skip this non-critical check:
|
for engine in engines.all():
|
||||||
# 1. if the user has a non-trivial TEMPLATES setting and Django
|
if isinstance(engine, DjangoTemplates):
|
||||||
# can't find a default template engine
|
django_templates_instance = engine.engine
|
||||||
# 2. if anything goes wrong while loading template engines, in
|
break
|
||||||
# order to avoid raising an exception from a confusing location
|
else:
|
||||||
# Catching ImproperlyConfigured suffices for 1. but 2. requires
|
django_templates_instance = None
|
||||||
# catching all exceptions.
|
if not django_templates_instance:
|
||||||
pass
|
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:
|
else:
|
||||||
if ('django.contrib.auth.context_processors.auth'
|
if ('django.contrib.auth.context_processors.auth'
|
||||||
not in default_template_engine.context_processors and
|
not in django_templates_instance.context_processors and
|
||||||
'django.contrib.auth.backends.ModelBackend' in settings.AUTHENTICATION_BACKENDS):
|
'django.contrib.auth.backends.ModelBackend'
|
||||||
missing_template = checks.Error(
|
in settings.AUTHENTICATION_BACKENDS):
|
||||||
"'django.contrib.auth.context_processors.auth' must be in "
|
errors.append(checks.Error(
|
||||||
"TEMPLATES in order to use the admin application.",
|
"'django.contrib.auth.context_processors.auth' must be "
|
||||||
id="admin.E402"
|
"enabled in DjangoTemplates (TEMPLATES) if using the default "
|
||||||
)
|
"auth backend in order to use the admin application.",
|
||||||
errors.append(missing_template)
|
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
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -624,7 +624,26 @@ The following checks are performed on the default
|
||||||
* **admin.E401**: :mod:`django.contrib.contenttypes` must be in
|
* **admin.E401**: :mod:`django.contrib.contenttypes` must be in
|
||||||
:setting:`INSTALLED_APPS` in order to use the admin application.
|
:setting:`INSTALLED_APPS` in order to use the admin application.
|
||||||
* **admin.E402**: :mod:`django.contrib.auth.context_processors.auth`
|
* **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``
|
``auth``
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -43,6 +43,8 @@ class MyAdmin(admin.ModelAdmin):
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.messages',
|
||||||
'admin_checks',
|
'admin_checks',
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -58,20 +60,42 @@ class SystemChecksTestCase(SimpleTestCase):
|
||||||
admin.site.unregister(Song)
|
admin.site.unregister(Song)
|
||||||
|
|
||||||
@override_settings(INSTALLED_APPS=['django.contrib.admin'])
|
@override_settings(INSTALLED_APPS=['django.contrib.admin'])
|
||||||
def test_contenttypes_dependency(self):
|
def test_apps_dependencies(self):
|
||||||
errors = admin.checks.check_dependencies()
|
errors = admin.checks.check_dependencies()
|
||||||
expected = [
|
expected = [
|
||||||
checks.Error(
|
checks.Error(
|
||||||
"'django.contrib.contenttypes' must be in "
|
"'django.contrib.contenttypes' must be in "
|
||||||
"INSTALLED_APPS in order to use the admin application.",
|
"INSTALLED_APPS in order to use the admin application.",
|
||||||
id="admin.E401",
|
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)
|
self.assertEqual(errors, expected)
|
||||||
|
|
||||||
@override_settings(TEMPLATES=[])
|
@override_settings(TEMPLATES=[])
|
||||||
def test_no_template_engines(self):
|
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(
|
@override_settings(
|
||||||
TEMPLATES=[{
|
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()
|
errors = admin.checks.check_dependencies()
|
||||||
expected = [
|
expected = [
|
||||||
checks.Error(
|
checks.Error(
|
||||||
"'django.contrib.auth.context_processors.auth' must be in "
|
"'django.contrib.auth.middleware.AuthenticationMiddleware' "
|
||||||
"TEMPLATES in order to use the admin application.",
|
"must be in MIDDLEWARE in order to use the admin application.",
|
||||||
id="admin.E402",
|
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)
|
self.assertEqual(errors, expected)
|
||||||
|
|
|
@ -1172,9 +1172,28 @@ class ManageCheck(AdminScriptTestCase):
|
||||||
'django.contrib.admin.apps.SimpleAdminConfig',
|
'django.contrib.admin.apps.SimpleAdminConfig',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.sessions',
|
||||||
],
|
],
|
||||||
sdict={
|
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']
|
args = ['check']
|
||||||
|
|
Loading…
Reference in New Issue