diff --git a/django/conf/project_template/project_name/settings.py b/django/conf/project_template/project_name/settings.py index efe8091e81..198a3e0d92 100644 --- a/django/conf/project_template/project_name/settings.py +++ b/django/conf/project_template/project_name/settings.py @@ -30,7 +30,7 @@ ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = ( - 'django.contrib.admin', + 'django.contrib.admin.apps.AdminConfig', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', diff --git a/django/conf/project_template/project_name/urls.py b/django/conf/project_template/project_name/urls.py index f03a29478d..d85c6f8e28 100644 --- a/django/conf/project_template/project_name/urls.py +++ b/django/conf/project_template/project_name/urls.py @@ -1,7 +1,5 @@ from django.conf.urls import patterns, include, url - from django.contrib import admin -admin.autodiscover() urlpatterns = patterns('', # Examples: diff --git a/django/contrib/admin/apps.py b/django/contrib/admin/apps.py index 980ff0c369..a8f0e91ea6 100644 --- a/django/contrib/admin/apps.py +++ b/django/contrib/admin/apps.py @@ -6,3 +6,6 @@ from django.utils.translation import ugettext_lazy as _ class AdminConfig(AppConfig): name = 'django.contrib.admin' verbose_name = _("administration") + + def ready(self): + self.module.autodiscover() diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 8b81f6c68e..010574f136 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -161,8 +161,8 @@ class AdminSite(object): 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.") + raise ImproperlyConfigured("Put 'django.contrib.admin.apps.AdminConfig' 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.") diff --git a/docs/intro/tutorial01.txt b/docs/intro/tutorial01.txt index 3fa07e132c..e79535661c 100644 --- a/docs/intro/tutorial01.txt +++ b/docs/intro/tutorial01.txt @@ -435,7 +435,7 @@ look like this: :filename: mysite/settings.py INSTALLED_APPS = ( - 'django.contrib.admin', + 'django.contrib.admin.apps.AdminConfig', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', @@ -444,6 +444,13 @@ look like this: 'polls', ) +.. admonition:: Doesn't match what you see? + + If you're seeing ``'django.contrib.admin'`` instead of + ``'django.contrib.admin.apps.AdminConfig'``, you're probably using a + version of Django that doesn't match this tutorial version. You'll want + to either switch to the older tutorial or the newer Django version. + Now Django knows to include the ``polls`` app. Let's run another command: .. code-block:: bash diff --git a/docs/intro/tutorial03.txt b/docs/intro/tutorial03.txt index 2e0159f1db..d443536c1a 100644 --- a/docs/intro/tutorial03.txt +++ b/docs/intro/tutorial03.txt @@ -105,15 +105,20 @@ with: :filename: mysite/urls.py from django.conf.urls import patterns, include, url - from django.contrib import admin - admin.autodiscover() urlpatterns = patterns('', url(r'^polls/', include('polls.urls')), url(r'^admin/', include(admin.site.urls)), ) +.. admonition:: Doesn't match what you see? + + If you're seeing ``admin.autodiscover()`` before the definition of + ``urlpatterns``, you're probably using a version of Django that doesn't + match this tutorial version. You'll want to either switch to the older + tutorial or the newer Django version. + You have now wired an ``index`` view into the URLconf. Go to http://localhost:8000/polls/ in your browser, and you should see the text "*Hello, world. You're at the polls index.*", which you defined in the @@ -587,9 +592,7 @@ it to include namespacing: :filename: mysite/urls.py from django.conf.urls import patterns, include, url - from django.contrib import admin - admin.autodiscover() urlpatterns = patterns('', url(r'^polls/', include('polls.urls', namespace="polls")), diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index efd72f58db..12d64d427a 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -23,8 +23,12 @@ The admin is enabled in the default project template used by For reference, here are the requirements: -1. Add ``'django.contrib.admin'`` to your :setting:`INSTALLED_APPS` - setting. +1. Add ``'django.contrib.admin.apps.AdminConfig'`` to your + :setting:`INSTALLED_APPS` setting. + + .. versionchanged:: 1.7 + + :setting:`INSTALLED_APPS` used to contain ``'django.contrib.admin'``. 2. The admin has four dependencies - :mod:`django.contrib.auth`, :mod:`django.contrib.contenttypes`, @@ -76,7 +80,7 @@ Other topics .. class:: ModelAdmin The ``ModelAdmin`` class is the representation of a model in the admin - interface. These are stored in a file named ``admin.py`` in your + interface. Usually, these are stored in a file named ``admin.py`` in your application. Let's take a look at a very simple example of the ``ModelAdmin``:: @@ -129,6 +133,36 @@ The register decorator class PersonAdmin(admin.ModelAdmin): pass +Discovery of admin files +------------------------ + +The admin needs to be instructed to look for ``admin.py`` files in your project. +The easiest solution is to put ``'django.contrib.admin.apps.AdminConfig'`` in +your :setting:`INSTALLED_APPS` setting. + +.. class:: django.contrib.admin.apps.AdminConfig + + .. versionadded:: 1.7 + + This class calls :func:`~django.contrib.admin.autodiscover()` when Django + starts. + +.. function:: django.contrib.admin.autodiscover + + This function attempts to import an ``admin`` module in each installed + application. Such modules are expected to register models with the admin. + + .. versionchanged:: 1.7 + + Previous versions of Django recommended calling this function directly + in the URLconf. :class:`~django.contrib.admin.apps.AdminConfig` + replaces that mechanism and is more robust. + +If you are using a custom ``AdminSite``, it is common to import all of the +``ModelAdmin`` subclasses into your code and register them to the custom +``AdminSite``. In that case, simply put ``'django.contrib.admin'`` in your +:setting:`INSTALLED_APPS` setting, as you don't need autodiscovery. + ``ModelAdmin`` options ---------------------- @@ -2377,15 +2411,10 @@ In this example, we register the default ``AdminSite`` instance from django.conf.urls import patterns, include from django.contrib import admin - admin.autodiscover() - urlpatterns = patterns('', (r'^admin/', include(admin.site.urls)), ) -Above we used ``admin.autodiscover()`` to automatically load the -:setting:`INSTALLED_APPS` admin.py modules. - In this example, we register the ``AdminSite`` instance ``myproject.admin.admin_site`` at the URL ``/myadmin/`` :: @@ -2397,9 +2426,11 @@ In this example, we register the ``AdminSite`` instance (r'^myadmin/', include(admin_site.urls)), ) -There is really no need to use autodiscover when using your own ``AdminSite`` -instance since you will likely be importing all the per-app admin.py modules -in your ``myproject.admin`` module. +Note that you don't need autodiscovery of ``admin`` modules when using your +own ``AdminSite`` instance since you will likely be importing all the per-app +``admin`` modules in your ``myproject.admin`` module. This means you likely do +not need ``'django.contrib.admin.app.AdminConfig'`` in your +:setting:`INSTALLED_APPS` and can just use ``'django.contrib.admin'``. Multiple admin sites in the same URLconf ---------------------------------------- diff --git a/docs/ref/contrib/gis/tutorial.txt b/docs/ref/contrib/gis/tutorial.txt index 4081a11157..f3eeb64e59 100644 --- a/docs/ref/contrib/gis/tutorial.txt +++ b/docs/ref/contrib/gis/tutorial.txt @@ -115,7 +115,7 @@ In addition, modify the :setting:`INSTALLED_APPS` setting to include and ``world`` (your newly created application):: INSTALLED_APPS = ( - 'django.contrib.admin', + 'django.contrib.admin.apps.AdminConfig', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', @@ -734,8 +734,6 @@ Next, edit your ``urls.py`` in the ``geodjango`` application folder as follows:: from django.conf.urls import patterns, url, include from django.contrib.gis import admin - admin.autodiscover() - urlpatterns = patterns('', url(r'^admin/', include(admin.site.urls)), ) diff --git a/docs/ref/contrib/index.txt b/docs/ref/contrib/index.txt index cd85b45487..3b57ba8c17 100644 --- a/docs/ref/contrib/index.txt +++ b/docs/ref/contrib/index.txt @@ -14,8 +14,8 @@ those packages have. For most of these add-ons -- specifically, the add-ons that include either models or template tags -- you'll need to add the package name (e.g., - ``'django.contrib.admin'``) to your :setting:`INSTALLED_APPS` setting and - re-run ``manage.py migrate``. + ``'django.contrib.redirects'``) to your :setting:`INSTALLED_APPS` setting + and re-run ``manage.py migrate``. .. _"batteries included" philosophy: http://docs.python.org/tutorial/stdlib.html#batteries-included diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index b2a740f0d5..7d58f7a7c8 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -93,6 +93,13 @@ Improvements thus far include: starts, through a deterministic and straightforward process. This should make it easier to diagnose import issues such as import loops. +* The admin has an :class:`~django.contrib.admin.apps.AdminConfig` application + configuration class. When Django starts, this class takes care of calling + :func:`~django.contrib.admin.autodiscover()`. To use it, simply replace + ``'django.contrib.admin'`` in :setting:`INSTALLED_APPS` with + ``'django.contrib.admin.apps.AdminConfig'`` and remove + ``admin.autodiscover()`` from your URLconf. + New method on Field subclasses ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~