Django Queryset统计用户Commit记录并实现过滤排序的方法咨询
实现方案
首先纠正你模型定义的小笔误:class Commit(odels.Model): 应为 class Commit(models.Model):
前置导入
from django.db.models import Count, Q from django.utils import timezone from django.contrib.auth import get_user_model # 确保已经导入你的Commit模型
核心代码实现
步骤1:计算时间阈值与排除条件
# 计算7天前的时间点,自动适配项目时区配置 seven_days_ago = timezone.now() - timezone.timedelta(days=7) # 替换为你自己的账号ID,若在视图中使用可直接取 request.user.id my_user_id = 1 # 示例ID
步骤2:构造QuerySet(两种常用实现方式)
方式1:从用户模型查询,直接返回带统计字段的用户对象列表
适配你Commit模型中定义的反向关联规则related_name="%(class)s_creator",自动生成的反向关联名为commit_creator:
active_user_list = get_user_model().objects.exclude( id=my_user_id # 排除自己的账号 ).annotate( # 统计该用户所有Commit总数 total_commits=Count('commit_creator'), # 统计该用户近7天的Commit数量,低版本Django也兼容 recent_commit_num=Count('commit_creator', filter=Q(commit_creator__date__gte=seven_days_ago)) ).filter( total_commits__gt=0, # 过滤无Commit记录的用户 recent_commit_num__gt=0 # 过滤近7天无提交的用户 ).order_by('-total_commits') # 按Commit总数从高到低排序
方式2:从Commit模型聚合,返回结构化统计字典
适合只需要统计结果、不需要完整用户对象的场景:
commit_statistics = Commit.objects.exclude( creator_id=my_user_id, creator__isnull=True # 排除creator为空的无效Commit记录 ).values( 'creator_id', 'creator__username' # 可自行扩展需要返回的用户字段 ).annotate( total_commits=Count('id'), recent_commit_num=Count('id', filter=Q(date__gte=seven_days_ago)) ).filter( recent_commit_num__gt=0 ).order_by('-total_commits')
注意事项
- 若你的Django版本 >= 3.2,方式1中的
recent_commit_num可简化为has_recent_commit=Q(commit_creator__date__gte=seven_days_ago),过滤条件对应改为has_recent_commit=True - 不要用Python原生的
datetime.now()计算时间,避免时区不匹配导致的过滤错误 - 如果你的User模型有自定义字段,可直接在
values或者查询链中添加需要返回的字段
内容的提问来源于stack exchange,提问作者bloupbloupbloup42
相关产品推荐
相关产品推荐

