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

在Django(Python)序列化器中分组任务日程数据的实现方法

解决方案:在Django Serializer中重组任务周数据结构

嗨,这个需求本质上就是按week_number对任务进行分组聚合,在Django Rest Framework(DRF)的Serializer里,我们可以通过SerializerMethodField来实现这个自定义的数据结构,下面给你两种实用的实现方案:

方案一:手动字典分组(直观易理解)

这种方式逻辑清晰,适合刚接触DRF的开发者,步骤如下:

1. 定义任务子Serializer

先写一个负责序列化单个任务条目的子Serializer,确保输出的任务格式符合要求:

from rest_framework import serializers

class TaskItemSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    task = serializers.IntegerField()

2. 主Serializer中实现分组逻辑

在主Serializer里用SerializerMethodField来生成目标的weeks字段,核心是用字典按周号分组任务:

class MainSerializer(serializers.Serializer):
    weeks = serializers.SerializerMethodField()

    def get_weeks(self, obj):
        # 从序列化对象中获取原始的周任务数据
        # 如果是模型实例,改成obj.week_task_schedule.all()即可
        week_tasks = obj.get('week_task_schedule', [])
        
        # 初始化字典用于分组:键为week_number,值为对应任务列表
        grouped_tasks = {}
        for item in week_tasks:
            week_num = item['week_number']
            # 若当前周号不在分组字典中,先创建空列表
            if week_num not in grouped_tasks:
                grouped_tasks[week_num] = []
            # 将当前任务添加到对应周的列表
            grouped_tasks[week_num].append({
                'id': item['id'],
                'task': item['task']
            })
        
        # 将分组后的字典转换为目标列表格式,并按周号排序
        sorted_weeks = sorted(grouped_tasks.items(), key=lambda x: x[0])
        return [
            {
                'week_number': week_num,
                'tasks': TaskItemSerializer(tasks, many=True).data
            }
            for week_num, tasks in sorted_weeks
        ]

方案二:使用itertools.groupby(简洁高效)

如果你喜欢更简洁的写法,可以用Python标准库的itertools.groupby,但要注意必须先对原始数据按week_number排序,否则分组会失效:

from rest_framework import serializers
from itertools import groupby

class TaskItemSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    task = serializers.IntegerField()

class MainSerializer(serializers.Serializer):
    weeks = serializers.SerializerMethodField()

    def get_weeks(self, obj):
        week_tasks = obj.get('week_task_schedule', [])
        # 关键:先按week_number排序,确保groupby能正确分组
        sorted_tasks = sorted(week_tasks, key=lambda x: x['week_number'])
        # 按week_number分组
        week_groups = groupby(sorted_tasks, key=lambda x: x['week_number'])
        
        # 转换为目标格式
        return [
            {
                'week_number': week_num,
                'tasks': TaskItemSerializer(list(task_group), many=True).data
            }
            for week_num, task_group in week_groups
        ]

注意事项

  • 如果你的数据来自Django模型实例(而非字典),只需要将obj.get('week_task_schedule', [])替换为模型的关联字段查询,比如obj.week_task_schedule.all(),同时遍历的时候访问模型属性(如item.week_number、item.id)即可。
  • 两种方案都会输出按周号从小到大排序的结果,符合你给出的目标结构要求。

内容的提问来源于stack exchange,提问作者Luís Melo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:22:39