如何基于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
相关产品推荐
相关产品推荐

