You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决Django异步视图中SynchronousOnlyOperation报错问题

问题解决:Django异步视图中SynchronousOnlyOperation报错

问题原因

你遇到的报错核心是QuerySet的惰性求值特性:虽然用@sync_to_async包装了查询函数,但filter()返回的QuerySet并没有立即执行数据库查询,而是等到模板中执行{% for education in educations %}遍历操作时,才触发实际的数据库请求——此时代码处于异步视图的上下文环境中,同步的数据库操作直接触发了SynchronousOnlyOperation异常。

而返回[Education.objects.first()]能正常运行,是因为first()会立即执行数据库查询,返回的是具体的模型实例,模板遍历仅访问实例属性(未触发新的同步数据库操作),因此不会报错。

解决方法

方法1:在同步函数中强制求值QuerySet

修改get_educations函数,将QuerySet转换为列表,让数据库查询在sync_to_async包裹的同步线程内完成:

@sync_to_async
def get_educations():
    # 用list()强制执行查询,返回普通列表而非惰性QuerySet
    return list(Education.objects.filter(highlight=True).order_by("-order"))

async def home(request):
    return render(request, "home.html", {
        "educations": await get_educations(),
    })

方法2:使用Django异步ORM(Django 3.1+支持)

如果你的Django版本≥3.1,可以直接使用官方提供的异步查询方法,无需手动包装同步函数:

async def home(request):
    # 用afetch_all()强制执行异步查询,返回结果列表
    educations = await Education.objects.filter(highlight=True).order_by("-order").afetch_all()
    return render(request, "home.html", {
        "educations": educations,
    })

注意:异步ORM的方法均以a开头(如afilter、aget),必须在异步函数内调用。

内容的提问来源于stack exchange,提问作者Alberto Sanmartin Martinez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 03:33:15