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
相关产品推荐
相关产品推荐

