Loading django/contrib/admin/apps.py +2 −1 Original line number Diff line number Diff line from django.apps import AppConfig from django.contrib.admin.checks import check_admin_app from django.contrib.admin.checks import check_admin_app, check_dependencies from django.core import checks from django.utils.translation import ugettext_lazy as _ Loading @@ -11,6 +11,7 @@ class SimpleAdminConfig(AppConfig): verbose_name = _("Administration") def ready(self): checks.register(check_dependencies, checks.Tags.admin) checks.register(check_admin_app, checks.Tags.admin) Loading django/contrib/admin/checks.py +43 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,8 @@ from __future__ import unicode_literals from itertools import chain from django.apps import apps from django.conf import settings from django.contrib.admin.utils import ( NotRelationField, flatten, get_fields_from_path, ) Loading @@ -12,6 +14,7 @@ from django.db import models from django.forms.models import ( BaseModelForm, BaseModelFormSet, _get_foreign_key, ) from django.template.engine import Engine def check_admin_app(**kwargs): Loading @@ -20,6 +23,46 @@ def check_admin_app(**kwargs): return system_check_errors def check_dependencies(**kwargs): """ Check that the admin's dependencies are correctly installed. """ 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 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) return errors class BaseModelAdminChecks(object): def check(self, admin_obj, **kwargs): Loading django/contrib/admin/sites.py +0 −38 Original line number Diff line number Diff line Loading @@ -7,7 +7,6 @@ from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.db.models.base import ModelBase from django.http import Http404, HttpResponseRedirect from django.template.engine import Engine from django.template.response import TemplateResponse from django.urls import NoReverseMatch, reverse from django.utils import six Loading Loading @@ -172,40 +171,6 @@ class AdminSite(object): """ return request.user.is_active and request.user.is_staff def check_dependencies(self): """ Check that all things needed to run the admin have been correctly installed. The default implementation checks that admin and contenttypes apps are installed, as well as the auth context processor. """ if not apps.is_installed('django.contrib.admin'): raise ImproperlyConfigured( "Put 'django.contrib.admin' in your INSTALLED_APPS " "setting in order to use the admin application.") if not apps.is_installed('django.contrib.contenttypes'): raise ImproperlyConfigured( "Put 'django.contrib.contenttypes' in your INSTALLED_APPS " "setting in order to use the admin application.") 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 else: if ('django.contrib.auth.context_processors.auth' not in default_template_engine.context_processors): raise ImproperlyConfigured( "Enable 'django.contrib.auth.context_processors.auth' " "in your TEMPLATES setting in order to use the admin " "application.") def admin_view(self, view, cacheable=False): """ Decorator to create an admin view attached to this ``AdminSite``. This Loading Loading @@ -257,9 +222,6 @@ class AdminSite(object): # and django.contrib.contenttypes.views imports ContentType. from django.contrib.contenttypes import views as contenttype_views if settings.DEBUG: self.check_dependencies() def wrap(view, cacheable=False): def wrapper(*args, **kwargs): return self.admin_view(view, cacheable)(*args, **kwargs) Loading docs/ref/checks.txt +10 −0 Original line number Diff line number Diff line Loading @@ -409,6 +409,16 @@ registered as an inline on a :class:`~django.contrib.admin.ModelAdmin`. * **admin.E304**: ``<model>`` has no ``GenericForeignKey`` using content type field ``<field name>`` and object ID field ``<field name>``. AdminSite ~~~~~~~~~ The following checks are performed on the default :class:`~django.contrib.admin.AdminSite`: * **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. Auth ---- Loading tests/admin_checks/tests.py +38 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,44 @@ class SystemChecksTestCase(SimpleTestCase): admin.site.unregister(Song) admin.sites.system_check_errors = [] @override_settings(INSTALLED_APPS=['django.contrib.admin']) def test_contenttypes_dependency(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", ) ] self.assertEqual(errors, expected) @override_settings( INSTALLED_APPS=[ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', ], TEMPLATES=[{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [], }, }], ) def test_auth_contextprocessor_dependency(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", ) ] self.assertEqual(errors, expected) @override_settings(DEBUG=True) def test_custom_adminsite(self): class CustomAdminSite(admin.AdminSite): Loading Loading
django/contrib/admin/apps.py +2 −1 Original line number Diff line number Diff line from django.apps import AppConfig from django.contrib.admin.checks import check_admin_app from django.contrib.admin.checks import check_admin_app, check_dependencies from django.core import checks from django.utils.translation import ugettext_lazy as _ Loading @@ -11,6 +11,7 @@ class SimpleAdminConfig(AppConfig): verbose_name = _("Administration") def ready(self): checks.register(check_dependencies, checks.Tags.admin) checks.register(check_admin_app, checks.Tags.admin) Loading
django/contrib/admin/checks.py +43 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,8 @@ from __future__ import unicode_literals from itertools import chain from django.apps import apps from django.conf import settings from django.contrib.admin.utils import ( NotRelationField, flatten, get_fields_from_path, ) Loading @@ -12,6 +14,7 @@ from django.db import models from django.forms.models import ( BaseModelForm, BaseModelFormSet, _get_foreign_key, ) from django.template.engine import Engine def check_admin_app(**kwargs): Loading @@ -20,6 +23,46 @@ def check_admin_app(**kwargs): return system_check_errors def check_dependencies(**kwargs): """ Check that the admin's dependencies are correctly installed. """ 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 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) return errors class BaseModelAdminChecks(object): def check(self, admin_obj, **kwargs): Loading
django/contrib/admin/sites.py +0 −38 Original line number Diff line number Diff line Loading @@ -7,7 +7,6 @@ from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.db.models.base import ModelBase from django.http import Http404, HttpResponseRedirect from django.template.engine import Engine from django.template.response import TemplateResponse from django.urls import NoReverseMatch, reverse from django.utils import six Loading Loading @@ -172,40 +171,6 @@ class AdminSite(object): """ return request.user.is_active and request.user.is_staff def check_dependencies(self): """ Check that all things needed to run the admin have been correctly installed. The default implementation checks that admin and contenttypes apps are installed, as well as the auth context processor. """ if not apps.is_installed('django.contrib.admin'): raise ImproperlyConfigured( "Put 'django.contrib.admin' in your INSTALLED_APPS " "setting in order to use the admin application.") if not apps.is_installed('django.contrib.contenttypes'): raise ImproperlyConfigured( "Put 'django.contrib.contenttypes' in your INSTALLED_APPS " "setting in order to use the admin application.") 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 else: if ('django.contrib.auth.context_processors.auth' not in default_template_engine.context_processors): raise ImproperlyConfigured( "Enable 'django.contrib.auth.context_processors.auth' " "in your TEMPLATES setting in order to use the admin " "application.") def admin_view(self, view, cacheable=False): """ Decorator to create an admin view attached to this ``AdminSite``. This Loading Loading @@ -257,9 +222,6 @@ class AdminSite(object): # and django.contrib.contenttypes.views imports ContentType. from django.contrib.contenttypes import views as contenttype_views if settings.DEBUG: self.check_dependencies() def wrap(view, cacheable=False): def wrapper(*args, **kwargs): return self.admin_view(view, cacheable)(*args, **kwargs) Loading
docs/ref/checks.txt +10 −0 Original line number Diff line number Diff line Loading @@ -409,6 +409,16 @@ registered as an inline on a :class:`~django.contrib.admin.ModelAdmin`. * **admin.E304**: ``<model>`` has no ``GenericForeignKey`` using content type field ``<field name>`` and object ID field ``<field name>``. AdminSite ~~~~~~~~~ The following checks are performed on the default :class:`~django.contrib.admin.AdminSite`: * **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. Auth ---- Loading
tests/admin_checks/tests.py +38 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,44 @@ class SystemChecksTestCase(SimpleTestCase): admin.site.unregister(Song) admin.sites.system_check_errors = [] @override_settings(INSTALLED_APPS=['django.contrib.admin']) def test_contenttypes_dependency(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", ) ] self.assertEqual(errors, expected) @override_settings( INSTALLED_APPS=[ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', ], TEMPLATES=[{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [], }, }], ) def test_auth_contextprocessor_dependency(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", ) ] self.assertEqual(errors, expected) @override_settings(DEBUG=True) def test_custom_adminsite(self): class CustomAdminSite(admin.AdminSite): Loading