Django3+WebSocket(ASGI/Uvicorn)生产环境循环导入错误如何解决?
核心错误原因
你当前的asgi.py存在导入顺序错误:你在Django环境变量配置完成前,就提前导入了Channels组件、自定义路由apps.drivers.routing等依赖Django初始化的模块,这些模块导入时会触发关联的models、业务代码加载,此时Django还未完成初始化,就会抛出模块部分初始化的导入错误,表象和循环导入一致。
修复步骤
1. 修正asgi.py的导入顺序
必须先配置Django环境变量,再导入所有依赖Django初始化的模块,修正后的代码如下:
import os # 第一步:先配置Django环境变量,这行必须放在所有Django相关导入之前 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings') # 第二步:再导入Django、Channels相关组件 from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from django.core.asgi import get_asgi_application from channels.http import AsgiHandler # 第三步:最后导入自定义的业务路由、应用代码 from apps.drivers import routing application = ProtocolTypeRouter({ "http": AsgiHandler(), "websocket": AuthMiddlewareStack( URLRouter( routing.websocket_urlpatterns ) ), })
2. 移除手动添加的django.setup()代码
删除你在settings.py、asgi.py中手动添加的django.setup()调用,ASGI服务启动时会自动完成Django初始化,手动调用时机不对反而会触发重复加载、提前加载的问题。
3. 调整启动命令验证
先去掉gunicorn启动命令中的--preload参数测试,--preload会在worker fork前预加载代码,如果你有其他模块初始化依赖顺序问题,预加载会放大错误:
gunicorn project.asgi -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8009
本地运行正常的原因
本地使用python manage.py runserver启动时,Django会先完成自身初始化、加载完所有配置后,才会加载应用的ASGI/WSGI代码,导入顺序是正确的,所以不会触发错误。
内容的提问来源于stack exchange,提问作者Artush Ghazaryan
相关产品推荐
相关产品推荐

