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

Django实现按Order和Category分组并在Serializer中格式化返回结果

Django按order和category合并AnswerLog数据实现方案

问题背景

现有Django模型ModelAnswer和AnswerLog,当前接口返回单个Answer对象的列表,需将相同order和category的条目合并,把answer字段改为数组形式。

实现步骤

1. 优化查询集,减少数据库查询

修改ListAnswerLogView的查询集,用select_related预加载所有关联数据,避免多次查询数据库:

class ListAnswerLogView(generics.ListAPIView):
    def get_queryset(self):
        return AnswerLog.objects.select_related(
            'answer', 
            'answer__questions', 
            'answer__questions__category'
        ).order_by('order', 'answer__questions__category__name')

2. 新增分组序列化器

创建专门处理分组结构的序列化器,其中answer字段设置为多实例序列化模式:

class GroupedAnswerLogSerializer(serializers.Serializer):
    order = serializers.PositiveIntegerField()
    category = serializers.CharField()
    answer = ListAnswerSerializer(many=True)

3. 重写视图list方法实现分组逻辑

用itertools.groupby对查询结果按order和category分组,再将分组后的数据传入新序列化器:

import itertools

class ListAnswerLogView(generics.ListAPIView):
    serializer_class = serializers.GroupedAnswerLogSerializer

    def get_queryset(self):
        return AnswerLog.objects.select_related(
            'answer', 
            'answer__questions', 
            'answer__questions__category'
        ).order_by('order', 'answer__questions__category__name')

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        
        # 定义分组依据:order和category的组合
        def group_key(item):
            return (item.order, item.answer.questions.category.name)
        
        grouped_data = []
        # 遍历分组结果,组装成目标格式
        for (order, category), group in itertools.groupby(queryset, key=group_key):
            grouped_data.append({
                'order': order,
                'category': category,
                'answer': [item.answer for item in group]
            })
        
        serializer = self.get_serializer(grouped_data, many=True)
        return Response(serializer.data)

最终返回效果

接口将返回合并后的结构,符合预期格式:

[{
    "answer": [{
        "id": 42,
        "user": 1,
        "questions": "what did you do today",
        "subcategory": "Circumstance",
        "is_intentional": "False",
        "answer": "I played well",
        "created_at": "2022-09-05T21:00:57.604051"
    }, {
        "id": 43,
        "user": 1,
        "questions": "what was your achievment?",
        "subcategory": "Result",
        "is_intentional": "False",
        "answer": "a broked my leg",
        "created_at": "2022-09-05T21:00:57.626193"
    }],
    "order": 1,
    "category": "sports"
}]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:03:31