如何在Django注解中过滤日期范围统计TeamMember的Lead Opportunities数量
在Django的Count注解中添加日期范围过滤条件
基于给定的Django模型,我们需要统计指定日期范围内,每个TeamMember作为team_lead对应的Opportunity数量,并按数量从高到低排序。
现有模型定义
class TeamMember(models.Model): name = models.CharField(max_length=500) class Opportunity(models.Model): name = models.CharField(max_length=500) date_created = models.DateTimeField(auto_now=True) team_lead = models.ForeignKey('TeamMember', blank=False, related_name='lead_opps')
原无日期过滤的统计代码
# 统计所有时间范围内的机会数并排序 TeamMember.objects.annotate(num_opps=Count('lead_opps')).order_by('-num_opps')
带日期范围过滤的实现方案
要在Count注解中加入日期过滤,直接给Count添加filter参数,结合Q对象指定date_created的区间即可:
from django.utils import timezone from django.db.models import Count, Q # 定义目标日期范围(示例:2023全年) start_date = timezone.datetime(2023, 1, 1) end_date = timezone.datetime(2023, 12, 31, 23, 59, 59) # 带日期过滤的统计查询 team_members_stats = TeamMember.objects.annotate( num_opps=Count( 'lead_opps', filter=Q(lead_opps__date_created__range=(start_date, end_date)), distinct=True # 可选:如果存在重复关联场景,开启去重统计 ) ).order_by('-num_opps') # 获取排名第一的成员的机会数(需先判断查询集非空) if team_members_stats.exists(): top_member_count = team_members_stats[0].num_opps
关键说明
- 利用Django的双下划线
__关联到关联模型的字段,lead_opps__date_created表示TeamMember关联的Opportunity的date_created字段。 __range是Django ORM的区间查询操作符,用于匹配指定起止日期之间的记录。filter参数是Django 2.0及以上版本支持的注解过滤功能,只会统计符合条件的关联对象数量。- 如果你的项目启用了时区,确保日期对象是时区感知的(用
timezone模块生成日期即可)。
内容的提问来源于stack exchange,提问作者ChicagoMG2022
相关产品推荐
相关产品推荐

