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

如何基于Django的Mission模型筛选并汇总用户时长?

基于Mission的日期筛选并汇总Goal关联的Time时长

首先要明确Goal与Mission的关联关系——你提供的Goal模型里没有指向Mission的外键字段,这是实现需求的前提,需要先给Goal添加关联字段,比如:

class Goal(models.Model):
    # 保留原有STATUS及其他字段...
    id_ninja = models.ForeignKey(Ninja, null=True, on_delete=models.SET_NULL)
    id_user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    name = models.CharField(max_length=150, default='')
    description = models.TextField(default='')
    date_created = models.DateTimeField(null=True)
    status = models.CharField(max_length=20, choices=STATUS, default='in progress')
    # 添加关联Mission的外键
    mission = models.ForeignKey(Mission, on_delete=models.CASCADE, related_name="goals")

接下来你预想的写法存在语法错误(mission.month_created是不存在的字段),以下是正确的实现方式:

筛选符合Mission日期的Time记录

如果你已经拿到目标mission实例,可直接关联筛选对应Goal的Time记录,匹配Mission创建日期的年月:

times = Time.objects.filter(
    goal__mission=mission,
    day__year=mission.date_created.year,
    day__month=mission.date_created.month
)

如果是从单个goal实例出发(和你原有代码场景一致),可以通过Goal关联的Mission直接筛选:

times = goal.time_set.filter(
    day__year=goal.mission.date_created.year,
    day__month=goal.mission.date_created.month
)

高效汇总时长

你原来用循环累加的方式效率较低,推荐用Django的数据库聚合操作直接完成计算:

from django.db.models import Sum

# 汇总所有符合条件的Time总时长
total = times.aggregate(total_min=Sum('value'))['total_min'] or 0

# 如果需要按member_number分组汇总(假设Time包含member_number字段)
grouped_total = times.values('member_number').annotate(total_min=Sum('value'))
# 转成字典方便调用
total_min = {item['member_number']: item['total_min'] for item in grouped_total}

注意:如果mission.date_created可能为null,需要先做非空判断避免异常:

if mission.date_created:
    times = goal.time_set.filter(
        day__year=mission.date_created.year,
        day__month=mission.date_created.month
    )
else:
    times = goal.time_set.none()  # 无日期时返回空查询集

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:48:06