Django从1.8升级至1.9后出现AppRegistryNotReady错误求助
AppRegistryNotReady: Apps aren't loaded yet.错误 我之前从Django 1.8升级到1.9时也踩过这个坑,这个错误的根源是Django 1.9对应用加载流程做了严格规范——任何依赖应用模型、数据库连接的代码,必须等到Django完成应用注册表初始化后才能执行,而你的代码在django.setup()完成前就触发了这些操作。结合你的错误栈,给你几个针对性的解决方案:
1. 调整模型导入的时机
从错误栈能看到,accounts.py在模块顶层导入了UserAccountModel,而这个模型的父类TimeStampedModel在定义时会触发Django的应用注册表检查。在Django 1.9+中,模块级别的模型导入会因为应用未加载完成而报错。
解决办法:把模型导入移到函数/方法内部,而不是放在模块开头:
# 错误写法(模块顶层导入) from app_name.models.core import UserAccountModel def update_user_preference(): # 使用UserAccountModel pass # 正确写法(函数内延迟导入) def update_user_preference(): from app_name.models.core import UserAccountModel # 使用UserAccountModel pass
2. 修复WSGI文件的执行顺序
你的WSGI文件里,在调用get_wsgi_application()之前可能有隐性触发模型导入的代码,或者自定义的WSGI包装逻辑位置不对。get_wsgi_application()内部会调用django.setup(),这是初始化应用注册表的关键步骤。
确保WSGI文件的结构是这样的:
import os # 先设置settings环境变量 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "conf.settings") # 不要在这里放任何导入模型、执行数据库操作的代码 from django.core.wsgi import get_wsgi_application # 先初始化核心WSGI应用,完成应用加载 application = get_wsgi_application() # 再定义你的自定义WSGI包装逻辑 def start_response_with_id(env, start_response): # 你的自定义处理逻辑 pass def custom_application(env, start_response): return application(env, start_response_with_id) # 最后替换application为自定义版本(如果需要) application = custom_application
3. 延迟全局数据库操作
如果有代码在模块级别直接执行数据库操作(比如调用django.db.connection.cursor().execute()),这会直接触发错误——数据库连接的初始化依赖应用注册表加载完成。
推荐用AppConfig的ready()方法执行初始化:
- 在你的应用目录下创建/修改
apps.py:
from django.apps import AppConfig class YourAppConfig(AppConfig): name = 'app_name' # 你的应用名称 def ready(self): # 这个方法会在应用加载完成后自动执行 from django.db import connection with connection.cursor() as cursor: cursor.execute("你的SQL语句")
- 在
settings.py的INSTALLED_APPS里,把原来的应用名称替换成这个自定义的AppConfig:
INSTALLED_APPS = [ # ... 'app_name.apps.YourAppConfig', # 替换掉原来的'app_name' # ... ]
4. 排查第三方应用兼容性
有些老的第三方库可能没适配Django 1.9的应用加载流程,会在初始化时提前导入模型。你可以逐个注释掉INSTALLED_APPS里的第三方应用,重启服务排查是哪个应用导致的问题,然后升级到兼容Django 1.9的版本,或者寻找替代方案。
内容的提问来源于stack exchange,提问作者Vinay Kumar Sahu

