Django单个GET请求返回多个列表的实现及序列化报错解决
问题解答
1. 接口返回多个列表可行性
完全可以在同一个接口响应中返回多个列表,不需要为每个列表单独编写API,你的设计思路是合理的,非常适配看板类需求场景,还能减少前端的请求次数。
2. 报错原因
你遇到的ListSerializer 不可JSON序列化报错,是因为直接将序列化器对象放入了响应字典,没有提取序列化后的原生数据。
DRF的序列化器实例需要调用.data属性,才会生成可被JSON序列化的Python列表/字典结构,你省略了这个步骤,导致Response直接尝试序列化序列化器类本身,触发了类型错误。
3. 修复后的代码
只需要修改构造workspace_cards的三行代码,每个序列化器后添加.data即可:
class AllCardsView(generics.ListAPIView): # 顺便修正了原类名AllCardstView里多打的冗余字符t queryset = Card.objects.all() permission_classes = (IsAuthenticated,) serializer_class = Card_Serializer.CardAssigneeSerializer def get(self, request, pk=None): req_check = have_queryparams(request, 'team_pk') if not req_check.have_all: return Response({'error': req_check.error_message}, status=status.HTTP_400_BAD_REQUEST) team_pk = request.query_params.get("team_pk") cradlistDone = Card.objects.filter(team=team_pk, status="Done") cradlistInProgress = Card.objects.filter(team=team_pk, status="In progress") cradlistToDo = Card.objects.filter(team=team_pk, status="TO DO") workspace_cards={} # 每个序列化器后添加.data提取序列化结果 workspace_cards['ToDO'] = Card_Serializer.CardAssigneeSerializer(cradlistToDo, many=True).data workspace_cards['InProgress'] = Card_Serializer.CardAssigneeSerializer(cradlistInProgress, many=True).data workspace_cards['Done'] = Card_Serializer.CardAssigneeSerializer(cradlistDone, many=True).data return Response(workspace_cards, status=status.HTTP_200_OK)
4. 可选优化建议
原代码会对数据库发起3次查询,可以改成一次查询所有当前团队的卡片,再在内存中分组,减少数据库开销:
# 只查一次数据库 all_cards = Card.objects.filter(team=team_pk) # 内存分组 workspace_cards = { "ToDO": CardAssigneeSerializer([c for c in all_cards if c.status == "TO DO"], many=True).data, "InProgress": CardAssigneeSerializer([c for c in all_cards if c.status == "In progress"], many=True).data, "Done": CardAssigneeSerializer([c for c in all_cards if c.status == "Done"], many=True).data }
内容的提问来源于stack exchange,提问作者Zahra Hosseini
相关产品推荐
相关产品推荐

