You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何拆分Django应用Core为多文件夹?遇AppRegistryNotReady错误求解

Django Core应用拆分问题及解决

我尝试将名为Core的Django应用拆分为Bank、Currency等子文件夹,每个子文件夹包含views、urls、models、serializer文件及__init__.py,为模型配置了app_label,URL文件设置了app_name,但运行时出现AppRegistryNotReady: Apps aren't loaded yet错误。请问是否可以按此方式拆分?若不可行,该如何拆分以避免多个模型类存于同一文件?

配置详情

子文件夹示例结构

Bank
---views.py
---urls.py
---models.py
---serializer.py

Currency
---views.py
---urls.py
---models.py
---serializer.py

Bank文件夹__init__.py

from .models import BimaCoreBank

Bank文件夹models.py(示例)

from django.db import models
from core.abstract.models import AbstractModel
from core.country.models import BimaCoreCountry
from core.state.models import BimaCoreState


class BimaCoreBank(AbstractModel):
    name = models.CharField(max_length=128, blank=False, unique=True)
    street = models.CharField(max_length=256, blank=True, null=True)
    street2 = models.CharField(max_length=256, blank=True, null=True)
    zip = models.CharField(max_length=16, blank=True, null=True)
    city = models.CharField(max_length=16, blank=True, null=True)
    state = models.ForeignKey(
        BimaCoreState, on_delete=models.PROTECT)
    country = models.ForeignKey(
        BimaCoreCountry, on_delete=models.PROTECT)
    email = models.EmailField(blank=True, null=True)
    active = models.BooleanField(default=True)
    bic = models.CharField(max_length=16, blank=True, null=True)

    def __str__(self) -> str:
        return self.name

    class Meta:
        ordering = ['name']
        permissions = []
        app_label = "BimaCoreBank"

Bank文件夹urls.py

from rest_framework import routers

from core.bank.views import BimaCoreBankViewSet

router = routers.DefaultRouter()

app_name = 'BimaCoreBank'

urlpatterns = [
    router.register(r'bank', BimaCoreBankViewSet, basename='bank'),
]

Core文件夹__init__.py

from . import bank
from . import country
from . import currency
from . import state

Core文件夹urls.py

from django.urls import path, include

app_name = 'core'

urlpatterns = [
    path('currency/', include('currency.urls.py')),
    path('country/', include('country.urls.py')),
    path('state/', include('state.urls.py')),
    path('bank/', include('bank.urls.py'))
]

项目根urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/schema/', SpectacularAPIView.as_view(), name='api-schema'),
    path(
        'api/docs/',
        SpectacularSwaggerView.as_view(url_name='api-schema'),
        name='api-docs',
    ),
    path('api/user/', include('user.urls')),
    path('api/core/', include('core.urls'))

]

错误信息

(venv) rdm-bima@rdmbima-HP-EliteBook-850-G8-Notebook-PC:~/Downloads/bima_chiffre/app$ python3 manage.py runserver
Watching for file changes with StatReloader
Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/core/management/commands/runserver.py", line 125, in inner_run
    autoreload.raise_last_exception()
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/utils/autoreload.py", line 87, in raise_last_exception
    raise _exception[1]
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 398, in execute
    autoreload.check_errors(django.setup)()
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/apps/registry.py", line 91, in populate
    app_config = AppConfig.create(entry)
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/apps/config.py", line 193, in create
    import_module(entry)
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/home/rdm-bima/Downloads/bima_chiffre/app/core/__init__.py", line 1, in <module>
    from . import bank
  File "/home/rdm-bima/Downloads/bima_chiffre/app/core/bank/__init__.py", line 1, in <module>
    from .models import BimaCoreBank
  File "/home/rdm-bima/Downloads/bima_chiffre/app/core/bank/models.py", line 4, in <module>
    from core.abstract.models import AbstractModel
  File "/home/rdm-bima/Downloads/bima_chiffre/app/core/abstract/models.py", line 7, in <module>
    from auditlog.registry import auditlog
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/auditlog/registry.py", line 325, in <module>
    auditlog = AuditlogModelRegistry()
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/auditlog/registry.py", line 52, in __init__
    from auditlog.receivers import log_access, log_create, log_delete, log_update
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/auditlog/receivers.py", line 6, in <module>
    from auditlog.context import threadlocal
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/auditlog/context.py", line 9, in <module>
    from auditlog.models import LogEntry
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/auditlog/models.py", line 10, in <module>
    from django.contrib.contenttypes.fields import GenericRelation
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/contrib/contenttypes/fields.py", line 7, in <module>
    from django.contrib.contenttypes.models import ContentType
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/contrib/contenttypes/models.py", line 137, in <module>
    class ContentType(models.Model):
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/db/models/base.py", line 127, in __new__
    app_config = apps.get_containing_app_config(module)
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/apps/registry.py", line 260, in get_containing_app_config
    self.check_apps_ready()
  File "/home/rdm-bima/Downloads/bima_chiffre/venv/lib/python3.10/site-packages/django/apps/registry.py", line 138, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

settings.py中INSTALLED_APPS

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'auditlog',
    'drf_spectacular',
    'core',
    'user',

]

问题分析与解决

1. 能否按此方式拆分?

可以,但你的配置存在3个关键错误导致了AppRegistryNotReady:

  • 提前导入模型:Core的__init__.py直接导入子文件夹,子文件夹的__init__.py又导入模型,这会在Django完成应用加载前就触发模型初始化,导致AppRegistry未就绪。
  • app_label配置错误:模型的app_label应该设为父应用core,而不是模型类名BimaCoreBank——这些模型都属于Core应用,不是独立的Django应用。
  • URL导入路径错误:Core的urls.py中include('currency.urls.py')写法错误,不需要加.py后缀,且要写完整的包路径core.currency.urls。

2. 正确的拆分步骤

步骤1:修正模型的app_label

所有子文件夹中的模型,将app_label统一改为core:

class Meta:
    ordering = ['name']
    permissions = []
    app_label = "core"  # 替换原来的"BimaCoreBank"

步骤2:移除不必要的提前导入

  • 删除Core文件夹__init__.py中的所有导入语句:
    # 删掉这些内容
    # from . import bank
    # from . import country
    # from . import currency
    # from . import state
    
  • 删除子文件夹(如Bank)__init__.py中的模型导入,只在需要使用模型的地方(比如views、serializers)按需导入即可。

步骤3:修正URL路径

Core的urls.py中,include的路径要写完整的包路径,且去掉.py后缀:

from django.urls import path, include

app_name = 'core'

urlpatterns = [
    path('currency/', include('core.currency.urls')),
    path('country/', include('core.country.urls')),
    path('state/', include('core.state.urls')),
    path('bank/', include('core.bank.urls'))
]

步骤4:可选优化:自定义AppConfig(非必需)

如果需要对子模块进行更精细的控制,可在Core应用中创建apps.py:

# core/apps.py
from django.apps import AppConfig

class CoreConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'core'

然后在settings.py的INSTALLED_APPS中替换core为core.apps.CoreConfig:

INSTALLED_APPS = [
    # ...其他应用
    'core.apps.CoreConfig',
    'user',
]

3. 其他注意事项

  • 模型间的关联导入要确保路径正确,比如from core.country.models import BimaCoreCountry是正确写法。
  • 运行迁移时,Django会自动识别Core应用下所有子模块中的模型,因为它们的app_label都设置为core。

内容的提问来源于stack exchange,提问作者Rad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:33:07