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

Django+Celery任务查询模型返回数据出现AsyncResult无法序列化报错如何解决

错误根因

  1. 调用get_all.delay()返回的是AsyncResult类型的异步任务实例,而非任务的实际执行结果,你直接将该实例传入序列化器和Response对象,自然无法完成JSON序列化
  2. 即便你后续获取到任务返回值,当前任务中直接返回Django ORM查询集对象,Celery默认的JSON序列化器也不支持序列化模型类实例,依然会抛出序列化错误

解决方案

根据你的业务场景选择对应方案即可:

方案1:接口需要同步返回查询结果(适配你当前的需求)

你需要对两个文件的代码做调整:

  1. 修改tasks.py,将序列化逻辑移入任务内部,直接返回可JSON序列化的字典列表:
from celery.decorators import task
from .models import Dummy
from .serializers import DummySerializer

@task(name="get_all")
def get_all():
    dummies = Dummy.objects.all()
    # 任务内提前完成序列化,返回标准可序列化数据
    return DummySerializer(dummies, many=True).data
  1. 修改views.py,触发任务后等待执行完成再拿结果返回:
from rest_framework import status
from rest_framework.response import Response

@api_view(["GET"])
@authentication_classes([])
@permission_classes([])
def dummy_list_all(request):
    """
    list all dummy objects
    """
    if request.method == "GET":
        # 触发异步任务
        task_obj = get_all.delay()
        # 等待任务执行完成,timeout可根据业务需求调整
        result_data = task_obj.get(timeout=10)
        return Response(result_data, status=status.HTTP_200_OK)

注意:这种同步等待任务执行的模式,性能和直接在视图内执行查询没有差异,如果没有特殊的异步解耦需求,不需要把简单查询逻辑放到Celery中执行,直接在视图内查询返回即可。

方案2:纯异步场景(接口不需要同步返回结果)

如果业务允许前端后续拿结果,可采用任务ID轮询的方案:

  1. 新增任务结果查询接口:
from celery.result import AsyncResult
from rest_framework import status
from rest_framework.response import Response

@api_view(["GET"])
def query_task_result(request, task_id):
    task = AsyncResult(task_id)
    if task.ready():
        return Response({"status": "success", "data": task.result}, status=status.HTTP_200_OK)
    return Response({"status": "pending"}, status=status.HTTP_102_PROCESSING)
  1. 调整原视图逻辑,触发任务后直接返回任务ID:
@api_view(["GET"])
@authentication_classes([])
@permission_classes([])
def dummy_list_all(request):
    """
    list all dummy objects
    """
    if request.method == "GET":
        task_obj = get_all.delay()
        return Response({"task_id": task_obj.id}, status=status.HTTP_202_ACCEPTED)

前端拿到task_id后,轮询调用query_task_result接口获取最终结果即可。

内容的提问来源于stack exchange,提问作者digdigdoot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:36:01