Почему администратор admin.autodiscover() не запускается автоматически в Django при использовании администратора, почему он был спроектирован так, чтобы его вызывали явно?

Не помещая admin.autodiscover() в urls.py, страница администратора показывает You don't have permission to edit anything (См. поток SO).

Почему это так? Если вам нужно добавить admin.autodiscover() для редактирования информации с помощью администратора, даже если у вас есть имя суперпользователя и пароль для обеспечения безопасности, почему разработчики Django не запускали автоматически admin.autodiscover()?

Ответ 1

(edit: Obsoleted after Django 1.7+, не нужно больше, см. ответ Alasdair)

Я думаю, что это дает вам более точный контроль. Рассмотрим код contrib.admin.autodiscover:

def autodiscover():
    """
    Auto-discover INSTALLED_APPS admin.py modules and fail silently when
    not present. This forces an import on them to register any admin bits they
    may want.
    """

    import copy
    from django.conf import settings
    from django.utils.importlib import import_module
    from django.utils.module_loading import module_has_submodule

    for app in settings.INSTALLED_APPS:
        mod = import_module(app)
        # Attempt to import the app admin module.
        try:
            before_import_registry = copy.copy(site._registry)
            import_module('%s.admin' % app)
        except:
            # Reset the model registry to the state before the last import as
            # this import will have to reoccur on the next request and this
            # could raise NotRegistered and AlreadyRegistered exceptions
            # (see #8245).
            site._registry = before_import_registry

            # Decide whether to bubble up this error. If the app just
            # doesn't have an admin module, we can ignore the error
            # attempting to import it, otherwise we want it to bubble up.
            if module_has_submodule(mod, 'admin'):
                raise

Таким образом, он автоматически загрузит модули INSTALLED_APPS admin.py и сработает молча, когда не будет найден. Теперь есть случаи, когда вы на самом деле не хотите, чтобы, например, при использовании собственного AdminSite:

# urls.py
from django.conf.urls import patterns, url, include
from myproject.admin import admin_site

urlpatterns = patterns('',
    (r'^myadmin/', include(admin_site.urls)),
)

в этом случае вам не нужно вызывать autodiscovery().

Также есть другие случаи, когда вы хотите видеть или редактировать подмножество приложений ваших проектов с помощью администратора, а вызов autodiscovery() не позволит вам это сделать.

Ответ 2

До Django 1.7 рекомендуется отправить вызов admin.autodiscover() в urls.py. Это позволило отключить его при необходимости. Требование admin.autodiscover() вместо автоматического вызова было примером философии Python 'Явно лучше, чем неявное' в действии. Помните, что приложение django.contrib.admin не является обязательным, оно не устанавливается на каждом сайте, поэтому было бы бессмысленно всегда запускать автообнаружение.

В большинстве случаев автообнаружение работает достаточно хорошо. Однако, если вам требуется больше контроля, вы можете вручную импортировать файлы администрирования определенных приложений. Например, вы можете захотеть зарегистрировать несколько сайтов-админов с разными приложениями в каждом.

Загрузка приложения была refactored в Django 1.7. Элемент autodiscover() был перенесен в конфигурацию приложения по умолчанию для приложения admin. Это означает, что автообнаружение теперь запускается при загрузке приложения admin, и нет необходимости добавлять admin.autodiscover() в urls.py. Если вы не хотите автообнаружения, теперь вы можете отключить его, используя SimpleAdminConfig.

Ответ 3

Django не требует использования django. contrib.admin на каждом сайте - это не основной модуль.