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

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错误。

具体修正步骤

  1. 移除模块级别的模型导入
    删除apps.py顶部的from .models import ...语句,不要在模块初始化阶段导入任何Django模型。

  2. 在需要使用模型的函数内部导入
    把模型导入移到实际使用的方法中(比如process方法),此时Django应用已经加载完成:

    def process(self, data):
        from .models import CryptoTicker, CryptoTrade, CryptoOrderbookMain, CryptoOrderbookSub
        # 后续处理逻辑
    
  3. 补充缺失的依赖导入
    原代码中缺少threading和websocket的导入,以及headers的定义,需要补上:

    import threading
    import websocket
    
    # 定义headers(根据实际需求调整)
    headers = {"Content-Type": "application/json"}
    
  4. 修正后的完整代码

    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 22:17:33