django 5.0 异步 orm 方法(如 aget、afilter)需同时满足 asgi 环境、异步驱动(如 asyncpg/asyncmy)、全程使用 a 前缀方法,缺一则静默降级为同步执行。

Django 5.0 的 aget()、afilter() 等异步 ORM 方法不会自动生效——必须同时满足三个条件:使用 ASGI 模式、更换为真正异步的数据库驱动、全程只调用带 a 前缀的方法。缺一不可,否则静默退化为同步执行,且不报错。
确认并切换到真正的异步数据库驱动
PostgreSQL 必须用 asyncpg,MySQL 推荐用 asyncmy(比 aiomysql 更轻量、更活跃)。psycopg2 和 sqlite3 完全不支持异步 ORM,哪怕写了 await User.objects.aget() 也会回退到同步阻塞。
- 卸载旧驱动:
pip uninstall psycopg2 psycopg2-binary(PostgreSQL)或pip uninstall PyMySQL mysqlclient(MySQL) - 安装新驱动:
pip install asyncpg或pip install asyncmy - 修改
DATABASES配置:
PostgreSQL 改为'ENGINE': 'django.db.backends.postgresql_async';
MySQL 改为'ENGINE': 'django.db.backends.mysql_async' - 启动服务后检查日志,出现
AsyncDatabaseWrapper初始化记录才算成功
只在 ASGI 环境中启用,且禁用同步中间件
WSGI 下跑 async 视图只是“伪异步”:每个请求会开一个独立事件循环,无法复用连接池,也享受不到全链路非阻塞的好处。
- 确保设置了
ASGI_APPLICATION = "myproject.asgi.application" - 检查中间件列表:任何未声明支持异步的中间件(比如自定义的
process_request)都会迫使 Django 启动线程模拟同步上下文 - 运行时开启
django.request的 DEBUG 日志,留意是否有"asynchronous handler adapting middleware"提示
避免混用同步与异步 ORM 方法
这是最隐蔽的性能陷阱:User.objects.get() 这样一行同步调用,就足以让整个视图函数放弃协程上下文,后续所有 await 都变成无效等待。
- ✅ 正确写法:
user = await User.objects.aget(id=1)、posts = await Post.objects.aprefetch_related('author').afilter(status='published') - ❌ 错误写法:
User.objects.get()、Post.objects.all()、obj.save()—— 即使只出现一次,整条链路就降级了 -
acount()、aexists()、afirst()全都可用;但all()本身不返回协程,必须写成await MyModel.objects.all() - 大结果集建议用
async for obj in MyModel.objects.afilter():流式处理,避免内存爆掉
配置连接池参数,否则异步优势几乎归零
异步 ORM 的瓶颈往往不在 Python 层,而在每次查询都要新建数据库连接。不配连接池,asyncpg 和 asyncmy 的并发能力根本发挥不出来。
- PostgreSQL 示例(
asyncpg特有):'OPTIONS': {'min_size': 5, 'max_size': 20, 'command_timeout': 60} - MySQL 示例(
asyncmy):'OPTIONS': {'max_connections': 20} - 务必设置
'CONN_MAX_AGE': 600(单位秒),否则连接无法复用,池子形同虚设 -
min_size和max_size不是越大越好,需结合实际 QPS 和 DB 连接数上限压测调整
最容易被忽略的是:驱动换对了、ASGI 跑起来了、代码也全加了 await,但没配 CONN_MAX_AGE 或连接池参数,结果性能还不如同步——因为每查一次都在建连、断连。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











