如何拆分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
相关产品推荐
相关产品推荐

