Django 3.0搭配Uvicorn启动提示ASGI lifespan不支持,如何兼容而非关闭?
嘿,这个问题我刚好踩过坑,来给你捋清楚前因后果和解决办法~
首先得明白为啥会出现那个提示:Django 3.0的ASGI支持是基础版本,并没有实现ASGI规范里的lifespan协议。这个协议主要是用来处理应用启动、关闭时的生命周期钩子(比如初始化全局资源、清理连接这类操作),Uvicorn默认会主动尝试启用这个协议,发现Django 3.0不支持,就会抛出ASGI 'lifespan' protocol appears unsupported的日志。
接下来分两种场景给你解决方案:
一、想要让Django 3.0支持Lifespan协议
如果你确实需要用到生命周期钩子功能,有两个可行方案:
1. 升级Django版本(最省心的方案)
Django从3.1版本开始正式支持ASGI的lifespan协议,升级到3.1或更高版本后,Uvicorn就能自动识别到lifespan支持,不需要额外加参数,启动日志里也不会再出现那个提示了。
2. 自定义ASGI中间件(不升级版本的折中方案)
如果因为各种原因没法升级Django 3.0,你可以自己写一个ASGI中间件,手动实现lifespan协议的处理逻辑:
# 在你的项目asgi.py文件里修改 import django from django.core.asgi import get_asgi_application # 初始化Django django.setup() # 获取原生Django ASGI应用 django_asgi_app = get_asgi_application() class LifespanMiddleware: def __init__(self, app): self.app = app async def __call__(self, scope, receive, send): # 处理lifespan类型的请求 if scope['type'] == 'lifespan': while True: message = await receive() if message['type'] == 'lifespan.startup': # 在这里添加你的启动初始化逻辑 # 比如:初始化Redis连接、预加载配置等 await send({'type': 'lifespan.startup.complete'}) elif message['type'] == 'lifespan.shutdown': # 在这里添加你的关闭清理逻辑 # 比如:关闭数据库连接、释放资源等 await send({'type': 'lifespan.shutdown.complete'}) return # 其他类型的请求交给原生Django处理 await self.app(scope, receive, send) # 用自定义中间件包装后的应用作为启动入口 application = LifespanMiddleware(django_asgi_app)
修改完asgi.py后,直接用uvicorn your_project.asgi:application启动,Uvicorn就会识别到lifespan协议支持了。
二、不需要Lifespan功能的临时方案
如果你的项目根本用不到生命周期钩子,那你现在用的--lifespan off参数完全没问题,它只是告诉Uvicorn跳过lifespan协议的检测,不会影响Django的正常运行——毕竟Django 3.0本来就没用到这个功能。
另外补充下:你搜不到Django + lifespan相关内容的原因,是因为Django 3.0确实没有官方支持这个特性,所有相关的文档、讨论都是从Django 3.1之后才开始出现的,早期版本的资料自然很少~
内容的提问来源于stack exchange,提问作者aroooo




