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

如何在Django 4 REST Framework中通过POST批量查询数据?

实现思路与代码修改方案

核心思路

通过在现有MediasViewSet中新增自定义POST动作来实现批量查询,核心是:

  1. 接收POST传入的数组格式请求数据
  2. 批量查询数据库(避免循环单查,提升性能)
  3. 按请求顺序匹配结果,存在则返回序列化数据,不存在则返回null(符合JSON规范,对应Python的None)

具体代码修改

1. 修正序列化器的语法错误

你的MediaSerializer存在语法笔误,先修正:

class MediaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Media
        fields = ['id', 'name', 'processed_status']  # 修正model和fields的分隔

2. 给MediasViewSet添加批量查询动作

在现有类中新增自定义POST接口,保留原有GET查询逻辑不受影响:

from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import status

class MediasViewSet(viewsets.ModelViewSet):
    queryset = Media.objects.all().order_by('name')
    serializer_class = MediaSerializer
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
        
    def get_queryset(self, *args, **kwargs):
        # 保留原有GET单条查询逻辑
        queryset = super().get_queryset()
        if "name" in self.request.data:
            query = self.request.data['name']
            if query:
                queryset = Media.objects.filter(name=query)
        return queryset

    # 新增批量查询接口
    @action(detail=False, methods=['post'], url_path='batch-check')
    def batch_check(self, request):
        # 校验请求格式:必须是数组
        if not isinstance(request.data, list):
            return Response({"error": "请求数据必须是JSON数组"}, status=status.HTTP_400_BAD_REQUEST)
        
        # 提取所有待查询的name
        target_names = [item.get('name') for item in request.data]
        
        # 批量查询数据库,一次SQL查询搞定
        existing_medias = Media.objects.filter(name__in=[name for name in target_names if name])
        # 构建name到序列化数据的映射,方便快速匹配
        media_map = {media.name: MediaSerializer(media).data for media in existing_medias}
        
        # 按请求顺序生成结果
        result = []
        for name in target_names:
            if not name:
                result.append(None)
            else:
                result.append(media_map.get(name, None))
        
        return Response(result)

关键细节说明

  • 接口路径:默认路由下,该批量接口的访问路径为/medias/batch-check/
  • 性能优化:用name__in做批量查询,替代循环单查数据库,大幅减少SQL请求次数
  • 顺序保证:严格按照请求数组的顺序返回结果,确保每个位置的结果对应原请求的条目
  • 错误处理:校验请求格式,若传入非数组数据直接返回400错误
  • 兼容性:原有GET单条查询逻辑完全保留,不影响现有功能

请求响应示例

请求(POST到/medias/batch-check/):

[
    {"name": "media1"},
    {"name": "media2"},
    {"name": "media3"}
]

响应:

[
    {"id": "xxx-xxx-xxx", "name": "media1", "processed_status": "xxx"},
    null,
    {"id": "yyy-yyy-yyy", "name": "media3", "processed_status": "xxx"}
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 00:20:45