为什么Django在使用admin时不自动调用admin.autodiscover(),为什么它被设计成显式调用?

2024-06-02 05:54:54 发布

您现在位置:Python中文网/ 问答频道 /正文

没有在url.py中放入admin.autodiscover(),管理页面显示You don't have permission to edit anythingSee SO thread)。

为什么会这样?如果你总是需要添加admin.autodiscover()来使用管理员编辑信息,即使你有一个超级用户名和密码来保证安全,为什么Django开发人员没有自动触发admin.autodiscover()?。


Tags: topyyouurlsoadminhave页面
3条回答

Django不要求您在每个站点上使用Django.contrib.admin—它不是核心模块。

(编辑:Django 1.7+后作废,无需更多,见阿拉斯代尔答案)

我想是给你更好的控制。考虑一下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's 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

因此,它将自动加载已安装的_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()

还有一些时候,你只想通过admin查看或编辑项目的一个子集,而调用autodiscovery()将无法实现这一点。

在Django 1.7之前,建议将admin.autodiscover()调用放在url.py中。这使得它在必要时可以被禁用。需要admin.autodiscover()而不是自动调用它,这是Python哲学'Explicit is better than implicit'在实际操作中的一个例子。记住,django.contrib.admin应用程序是可选的,它并不是安装在每个站点上,所以总是运行autodiscover是没有意义的。

大多数情况下,自动发现工作得很好。但是,如果需要更多控制,则可以手动导入特定应用的管理文件。例如,您可能希望在每个应用程序中使用不同的应用程序注册multiple admin sites

Django 1.7中的应用程序加载是refactoredautodiscover()已移动到管理应用程序的默认应用程序配置。这意味着autodiscover现在在加载管理应用程序时运行,不需要将admin.autodiscover()添加到url.py中。如果不需要自动发现,现在可以使用^{}来禁用它。

相关问题 更多 >