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

如何按预订日期分组Django的Ticket模型并获取每日工单ID列表

获取按日期分组的Django工单ID列表

嗨,我来帮你搞定这个需求!你已经实现了按日期统计工单总数,现在要改成获取每日的工单ID列表,这里有两种实用方案,我给你详细拆解:

方案一:数据库层面聚合(推荐,效率更高)

直接利用Django的数据库函数在数据库端完成分组和聚合,适合数据量较大的场景,性能表现更好。需要用到TruncDate(截断日期字段到天)和ArrayAgg(聚合ID为数组),注意ArrayAgg是PostgreSQL专属函数,如果你用其他数据库可能需要调整:

from django.db.models import ArrayAgg
from django.db.models.functions import TruncDate

# 按日期分组,聚合每个日期对应的工单ID列表
ticket_groups = Ticket.objects.annotate(
    # 将booked_at的时分秒截断,只保留日期部分
    day=TruncDate('booked_at')
).values('day').annotate(
    # 把当前日期下所有工单的ID聚合为列表
    ticket_list=ArrayAgg('id')
).order_by('day')

# 转换成你需要的列表格式
result = list(ticket_groups)

执行后result的格式就和你预期的完全一致了:每个元素包含day(带日期的datetime对象)和ticket_list(对应日期的工单ID数组)。

方案二:Python层面分组(灵活度更高)

如果你的业务需要直接操作工单对象,或者用的是不支持ArrayAgg的数据库,可以先查询所有工单,再用Python的itertools.groupby做分组:

from itertools import groupby
from django.utils import timezone

# 必须先按预订日期排序,groupby只能对连续相同的键分组
tickets = Ticket.objects.order_by('booked_at')

result = []
# 按预订日期的“日期部分”作为分组键
for day_date, ticket_group in groupby(tickets, key=lambda t: t.booked_at.date()):
    # 收集当前日期下所有工单的ID
    ticket_ids = [ticket.id for ticket in ticket_group]
    # 把date对象转成带时区的datetime对象(和示例格式匹配)
    aware_day = timezone.make_aware(timezone.datetime(day_date.year, day_date.month, day_date.day))
    result.append({
        'day': aware_day,
        'ticket_list': ticket_ids
    })

两种方案对比

  • 方案一:数据库直接处理,速度快,内存占用低,适合大数据量;但依赖特定数据库的聚合函数特性。
  • 方案二:纯Python处理,更灵活,能直接获取工单对象进行后续操作;但数据量很大时,处理速度和内存占用会不如方案一。

如果需要返回工单对象列表而不是ID列表,只需要把方案二中的ticket_ids = [ticket.id ...]改成ticket_objects = list(ticket_group),再将ticket_list替换为ticket_objects就可以啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:55:48