Django项目启动遇AppRegistryNotReady及populate()非可重入问题求助
Django AppRegistryNotReady 问题解决
项目结构
watcher |-config |-__init__.py |- asgi.py |- config.ini |- settings.py |- urls.py |- wsgi.py |-tower |-__init__.py |-admin.py |-apps.py |-models.py |-tests.py |-views.py |-manage.py
原始 tower/apps.py 代码
# import os # os.environ.setdefault("DJANGO_SETTINGS_MODULE", "watcher.settings") # import django # django.setup() from .models import CryptoTicker, CryptoTrade, CryptoOrderbookMain, CryptoOrderbookSub class TowerConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'tower' def ready(self): print("Hello") socket = SocketClient() socket.start() class SocketClient(threading.Thread): def __init__(self): super().__init__() self.url = "wss://api.upbit.com/websocket/v1" self.ws = websocket.WebSocketApp( url=self.url, header=headers, on_message=self.on_message, on_error=self.on_error, on_close=self.on_close, on_open=self.on_open ) self.step = 0 def run(self): while True: self.ws.run_forever() def on_message(self, ws, message): data = message.decode('utf-8') self.process(data) if self.step < 0: print("----- ----- ----- ----- ----- ----- -----") print() print(data) print() print("----- ----- ----- ----- ----- ----- -----") self.step += 1 def on_error(self, ws, err): print(err) def on_close(self, ws, status_code, msg): print("closed!") def on_open(self, ws): print("connected!") ws.send('[{"ticket":"siren1"}, {"type":"ticker","codes":["KRW-BTC", "KRW-SOL"]}, {"type":"trade","codes":["KRW-BTC", "KRW-SOL"]}, {"type":"orderbook","codes":["KRW-BTC", "KRW-SOL"]}, {"format": "DEFAULT"}]') def process(self, data): pass
执行命令后的错误
执行命令 python manage.py runserver --noreload 0.0.0.0:8000 后出现:
File "D:\git\crypto-siren\venv\Lib\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.
尝试添加手动初始化代码后出现新错误:
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "watcher.settings") import django django.setup()
File "D:\git\crypto-siren\watcher\tower\apps.py", line 15, in <module> django.setup() File "D:\git\crypto-siren\venv\Lib\site-packages\django\__init__.py", line 24, in setup apps.populate(settings.INSTALLED_APPS) File "D:\git\crypto-siren\venv\Lib\site-packages\django\apps\registry.py", line 83, in populate raise RuntimeError("populate() isn't reentrant") RuntimeError: populate() isn't reentrant
解决方法
核心原因
模块级别直接导入模型时,Django的应用注册表还未完成加载,触发AppRegistryNotReady错误;手动调用django.setup()会导致Django重复初始化应用注册表,引发populate() isn't reentrant错误。
具体修正步骤
移除模块级别的模型导入
删除apps.py顶部的from .models import ...语句,不要在模块初始化阶段导入任何Django模型。在需要使用模型的函数内部导入
把模型导入移到实际使用的方法中(比如process方法),此时Django应用已经加载完成:def process(self, data): from .models import CryptoTicker, CryptoTrade, CryptoOrderbookMain, CryptoOrderbookSub # 后续处理逻辑补充缺失的依赖导入
原代码中缺少threading和websocket的导入,以及headers的定义,需要补上:import threading import websocket # 定义headers(根据实际需求调整) headers = {"Content-Type": "application/json"}修正后的完整代码
import threading import websocket headers = {"Content-Type": "application/json"} class TowerConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'tower' def ready(self): print("Hello") socket = SocketClient() socket.start() class SocketClient(threading.Thread): def __init__(self): super().__init__() self.url = "wss://api.upbit.com/websocket/v1" self.ws = websocket.WebSocketApp( url=self.url, header=headers, on_message=self.on_message, on_error=self.on_error, on_close=self.on_close, on_open=self.on_open ) self.step = 0 def run(self): while True: self.ws.run_forever() def on_message(self, ws, message): data = message.decode('utf-8') self.process(data) if self.step < 0: print("----- ----- ----- ----- ----- ----- -----") print() print(data) print() print("----- ----- ----- ----- ----- ----- -----") self.step += 1 def on_error(self, ws, err): print(err) def on_close(self, ws, status_code, msg): print("closed!") def on_open(self, ws): print("connected!") ws.send('[{"ticket":"siren1"}, {"type":"ticker","codes":["KRW-BTC", "KRW-SOL"]}, {"type":"trade","codes":["KRW-BTC", "KRW-SOL"]}, {"type":"orderbook","codes":["KRW-BTC", "KRW-SOL"]}, {"format": "DEFAULT"}]') def process(self, data): from .models import CryptoTicker, CryptoTrade, CryptoOrderbookMain, CryptoOrderbookSub # 在这里添加数据处理和模型操作逻辑
额外注意事项
- 确保
tower应用已经添加到config/settings.py的INSTALLED_APPS中:INSTALLED_APPS = [ # ...其他应用 'tower', ] - 使用
--noreload参数时,Django不会自动重载代码,修改后需要重启服务生效。
内容的提问来源于stack exchange,提问作者Yun
相关产品推荐
相关产品推荐

