Django 4.2+ 支持异步 ORM,但仅限 aget()、acount()、afirst() 等带 a 前缀方法;await QuerySet.filter() 会报 TypeError,因 QuerySet 不可等待,且无 aall()、avalues() 等异步链式方法。

async def 视图里直接 await Model.objects.ao() 会报错
Django 4.2+ 确实支持异步 ORM,但不是所有 QuerySet 方法都已异步化。直接写 await MyModel.objects.filter(...) 会抛出 TypeError: object QuerySet can't be used in 'await' expression —— 因为 QuerySet 本身不可等待,必须调用明确的异步方法。
目前(Django 4.2–5.1)只有少数几个 ORM 方法带 a 前缀: aget()、acount()、alatest()、aearliest()、afirst()、alast()、aiterator()、exists_async()(注意是 exists_async,不是 aexists)。
-
await MyModel.objects.filter(...).afirst()✅ 可用 -
await MyModel.objects.filter(...).acount()✅ 可用 -
await MyModel.objects.filter(...).aget(id=1)✅(但注意:aget()不接受filter()链式调用,只能单独用) -
await MyModel.objects.filter(...).all()❌ 无aall(),不支持 -
await MyModel.objects.filter(...).select_related(...)❌ 异步版aselect_related()尚未实现(Django 5.1 仍无)
想异步查多条数据?只能用 aiterator() + list() 或手动 await
没有 aall() 或 alist(),所以不能直接把整个 QuerySet 异步转成 list。常见做法是用 aiterator() 流式获取,再收集:
<pre class="brush:php;toolbar:false;">async def my_view(request):
results = []
async for obj in MyModel.objects.filter(status="active").aiterator():
results.append(obj)
return JsonResponse({"count": len(results)})
注意两点:
立即学习“Python免费学习笔记(深入)”;
aiterator() 默认 chunk_size=2000,对大表可降低内存压力,但小查询没必要改- 不能在
aiterator()外部再链式调用order_by()或values()—— 这些方法本身不是异步的,且 Django 当前不支持异步版values()或only() - 如果真需要
values_list类行为,只能先aiterator()拿 model 实例,再手动取字段,比如[obj.name for obj in results]
数据库连接池和 async/pg 驱动必须配对启用
Django 异步 ORM 不是“开箱即用”,底层依赖异步数据库驱动和连接复用机制。默认 SQLite 不支持异步;PostgreSQL 必须用 django.db.backends.postgresql + asyncpg(Django 4.2+ 内置支持),MySQL 目前无官方异步后端。
配置关键点:
-
settings.py中DATABASES["default"]["ENGINE"]必须是django.db.backends.postgresql - 确保已安装
asyncpg(pip install asyncpg),Django 会自动检测并启用异步路径 - 若看到
RuntimeWarning: Async database connection attempted while running in sync mode,说明 Django 正在降级走同步路径 —— 很可能是用了psycopg2而非asyncpg,或数据库 ENGINE 写成了postgresql_psycopg2
混用 sync/async ORM 会导致死锁或连接泄漏
一个请求生命周期中,不能在 async def 视图里穿插调用同步 ORM(如 .save()、.delete()、.filter().first())。Django 的异步连接和同步连接使用不同连接池,混用可能卡住事件循环或耗尽连接。
- 所有 ORM 操作必须统一为异步接口:用
await obj.asave()替代obj.save(),用await obj.adelete()替代obj.delete() -
asave()和adelete()是模型实例方法,不是 QuerySet 方法,且仅对 PostgreSQL + asyncpg 有效 - 事务处理更受限:Django 当前不支持异步
transaction.atomic()块(async with transaction.atomic():会报错),需避免跨多个异步 ORM 调用的强一致性场景
最易被忽略的是信号(signals)—— post_save 等同步信号在异步视图中触发时,仍以同步方式执行,若信号处理器里又调了同步 ORM,就埋下死锁隐患。


















