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

如何将Celery返回的数据序列化到Django REST Framework响应中

问题根因分析

你遇到的空响应问题核心是两个错误叠加导致的:

  • 你用filter()查询单个主键对应的对象,返回的是QuerySet查询集合,而非单个模型实例,序列化单个实例时传入集合会直接返回空结果
  • 直接在DRF接口中调用result.get()是同步阻塞逻辑,会完全丧失Celery异步任务的优势,如果任务处理图片耗时较长还会直接触发接口超时
快速修复方案

修改你视图中查询实例和序列化的代码即可解决空响应问题:

class TestSet(viewsets.ModelViewSet):
    queryset = Test.objects.all()
    serializer_class = WebsiteURLSerializer

    def create(self, request, *args, **kwargs):
         serializer = WebsiteURLSerializer(data=request.data)
         if serializer.is_valid():
            url_site= serializer.validated_data['url']
            result = test_call.delay(url_site)
            # 原错误:filter返回QuerySet,改用get取单个实例,同时注意任务执行超时问题
            obj = ModelName.objects.get(pk=result.get())
            # 确认WebsiteURLSerializer是适配ModelName的序列化器,否则也会返回空
            result_unpacked = WebsiteURLSerializer(obj)
            return Response(result_unpacked.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@shared_task(name="values")
def test_call(url_image):
    model_instance = ModelName.objects.create()
    # 你的业务逻辑
    model_instance.save()
    return model_instance.id
更合理的异步实现方案

如果你的图片拉取和处理逻辑耗时超过2秒,完全不建议在接口中阻塞等待Celery任务执行完成,推荐改成异步交互逻辑:

  1. 接口提交Celery任务后直接返回任务ID给前端,HTTP状态码用202(已接受)
  2. 前端通过返回的任务ID轮询任务状态,或者接入WebSocket等待任务完成通知
  3. 任务执行完成后前端再调用查询接口拉取生成的实例数据

示例优化代码:

def create(self, request, *args, **kwargs):
    serializer = WebsiteURLSerializer(data=request.data)
    if serializer.is_valid():
        url_site= serializer.validated_data['url']
        result = test_call.delay(url_site)
        # 直接返回任务ID,不阻塞等待
        return Response({"task_id": result.id}, status=status.HTTP_202_ACCEPTED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# 新增任务状态查询接口
def get_task_status(request, task_id):
    task = AsyncResult(task_id)
    if task.ready():
        obj = ModelName.objects.get(pk=task.result)
        return Response(WebsiteURLSerializer(obj).data)
    return Response({"status": "processing"}, status=status.HTTP_200_OK)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:45:08