第一次在 async 视图里写 ORM,大多会撞上 SynchronousOnlyOperation。这篇把它出现的条件、几种正确写法、以及那个「关掉检查」的环境变量分别跑出来。
Item.objects.count() → SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async. list(Item.objects.all()) → SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async. Item.objects.create(name="x") → SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async. connection.cursor() → SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
不是只有查询才会触发:connection.cursor() 也一样。它检查的是「当前线程里有没有正在运行的事件循环」,而不是「这个函数是不是 async def」。
await Item.objects.acount() → 0 await sync_to_async(Item.objects.count)() → 0 [i async for i in Item.objects.all()] → 0 行
在 async 里直接 count() → 0
官方留它是为了 Jupyter 这类环境。在服务里打开它,只会让你失去这个提醒,同步查询照样阻塞整个事件循环里的所有请求。
/bad/ 状态码 500 页面标题: SynchronousOnlyOperation at /bad/ /good/ 状态码 200 内容: 0 检查用的装饰器(读源码): django/utils/asyncio.py 第 8 行:def async_unsafe(message):