无法同时覆盖 contrib.admin.AdminSite 和 django.contrib.auth.admin.UserAdmin

Unable to override both contrib.admin.AdminSite and django.contrib.auth.admin.UserAdmin simultaneously

使用 Django 3.1 和 Python 3.6,我试图覆盖默认的 AdminSite class 和 UserAdmin。我正在尝试结合文档两个不同部分的示例:

Overriding the default admin site

Extending the existing User model

最初我只有覆盖的 AdminSite class,但是当我也尝试覆盖 UserAdmin 时出现了问题。

这两个都是独立工作的。我可以覆盖 AdminSite 并获得自定义 header,或者 UserAdmin 并获得内联显示。

出于某种原因,我 运行 进入导入错误:ImportError: Module "core.admin" does not define a "CoreCustomAdmin" attribute/class。它看起来像是一种循环依赖,但这只是一个猜测,因为我无法弄清楚 where/how 它正在发生。

堆栈跟踪:

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/module_loading.py", line 20, in import_string
    return getattr(module, class_name)
AttributeError: module 'core.admin' has no attribute 'CoreCustomAdmin'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/module_loading.py", line 44, in autodiscover_modules
    if register_to:
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/functional.py", line 240, in inner
    self._setup()
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/contrib/admin/sites.py", line 540, in _setup
    AdminSiteClass = import_string(apps.get_app_config('admin').default_site)
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/module_loading.py", line 17, in import_string
    module = import_module(module_path)
  File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/infernous/project_name/src/core/admin.py", line 2, in <module>
    from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/contrib/auth/admin.py", line 26, in <module>
    class GroupAdmin(admin.ModelAdmin):
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/contrib/admin/decorators.py", line 21, in _model_admin_wrapper
    if not isinstance(admin_site, AdminSite):
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/functional.py", line 240, in inner
    self._setup()
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/contrib/admin/sites.py", line 540, in _setup
    AdminSiteClass = import_string(apps.get_app_config('admin').default_site)
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/module_loading.py", line 24, in import_string
    ) from err
ImportError: Module "core.admin" does not define a "CoreCustomAdmin" attribute/class

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/module_loading.py", line 20, in import_string
    return getattr(module, class_name)
AttributeError: module 'core.admin' has no attribute 'CoreCustomAdmin'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/autoreload.py", line 53, in wrapper
    fn(*args, **kwargs)
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 110, in inner_run
    autoreload.raise_last_exception()
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/autoreload.py", line 76, in raise_last_exception
    raise _exception[1]
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 357, in execute
    autoreload.check_errors(django.setup)()
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/autoreload.py", line 53, in wrapper
    fn(*args, **kwargs)
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/apps/registry.py", line 122, in populate
    app_config.ready()
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/contrib/admin/apps.py", line 24, in ready
    self.module.autodiscover()
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/contrib/admin/__init__.py", line 24, in autodiscover
    autodiscover_modules('admin', register_to=site)
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/module_loading.py", line 53, in autodiscover_modules
    if register_to:
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/functional.py", line 240, in inner
    self._setup()
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/contrib/admin/sites.py", line 540, in _setup
    AdminSiteClass = import_string(apps.get_app_config('admin').default_site)
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/module_loading.py", line 17, in import_string
    module = import_module(module_path)
  File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/infernous/project_name/src/core/admin.py", line 2, in <module>
    from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/contrib/auth/admin.py", line 26, in <module>
    class GroupAdmin(admin.ModelAdmin):
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/contrib/admin/decorators.py", line 21, in _model_admin_wrapper
    if not isinstance(admin_site, AdminSite):
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/functional.py", line 240, in inner
    self._setup()
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/contrib/admin/sites.py", line 540, in _setup
    AdminSiteClass = import_string(apps.get_app_config('admin').default_site)
  File "/home/infernous/project_name/.venv/lib/python3.6/site-packages/django/utils/module_loading.py", line 24, in import_string
    ) from err
ImportError: Module "core.admin" does not define a "CoreCustomAdmin" attribute/class

事实上,我没有加载默认管理员(无论如何都会出错)。

settings.py:

INSTALLED_APPS = [
    ...
    'core.apps.CoreCustomAdmin',
    ...
    # 'django.contrib.admin', # Commented out

问题文件?更改导入的顺序没有任何作用,这是预期的,因为它 Python:

core/admin.py:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User, Group

from allauth.account.models import UserData

class CoreCustomAdmin(admin.AdminSite):
    site_header = 'Custom Header'

class UserDataInline(admin.StackedInline):
    model = UserData
    can_delete = False

class CustomUserAdmin(BaseUserAdmin):
    inlines = (UserDataInline,)

admin.site = CoreCustomAdmin()
admin.site.register(User, CustomUserAdmin)
admin.site.register(Group)

我唯一导入的地方core.admin。我已经尝试将 admin.site = CoreCustomAdmin()core/admin.py 更改为 customadmin = CoreCustomAdmin() 之类的东西并使用它,但它自然没有任何作用。

urls.py

from django.urls import path, include

from core.admin import admin

app_name = 'project_name'
urlpatterns = [
    ...
    path('admin/', admin.site.urls),
]

core/apps.py

from django.apps import AppConfig
from django.contrib.admin.apps import AdminConfig


class CoreConfig(AppConfig):
    name = 'core'

class CoreCustomAdmin(AdminConfig):
    default_site = 'core.admin.CoreCustomAdmin'

谢谢!

我在 3 周后回到问题上并花了 5 分钟解决了这个问题后不小心修复了它。我将 settings.py 中的行从

更改为
'core.apps.CoreCustomAdmin',

'base.apps.AdminConfig',

它是 base.apps 而不是 core.apps 的原因是因为我根据对问题的评论将应用重命名为“base”,以试图解决问题。如果我不这样做,它只会将 CoreCustomAdmin 更改为 AdminConfig

据我所知,达到了预期的效果。它仍然在管理站点上有自定义 header,在用户模型编辑页面上也有内联。