如何用Django查询用户创建分类的当前及最长连续天数?
Django分类连续创建天数统计实现
问题背景
给定如下Django模型:
class CategoryModel(BaseModel): name = models.CharField(max_length=100) icon = models.ImageField(upload_to=upload_icon_image_to) description = models.CharField(max_length=100) user = models.ForeignKey(User,on_delete=models.CASCADE) def __str__(self): return self.name
需求为:用户单日创建1条或多条分类记录,均计为1天连续streak;次日继续创建则连续天数加1。需返回包含current_streak(当前连续天数)和max_streak(历史最长连续天数)的JSON结果:
{ "current_streak":3, "max_streak":12 }
实现方案
核心思路
- 提取用户创建分类的所有唯一日期(仅保留日期部分)并按时间升序排列;
- 遍历日期列表,统计所有连续日期段的长度,找出最长段作为
max_streak; - 检查最后一个连续段是否延续至今日,确定
current_streak(若今日未创建则连续中断,current_streak为0)。
代码实现
假设BaseModel包含created_at字段(自动记录创建时间),实现代码如下:
from datetime import date, timedelta from django.db.models.functions import TruncDate def get_category_streaks(user): # 获取用户创建分类的所有唯一日期,按升序排列 created_dates = list( CategoryModel.objects.filter(user=user) .annotate(only_date=TruncDate('created_at')) .values_list('only_date', flat=True) .distinct() .order_by('only_date') ) # 无创建记录时返回初始值 if not created_dates: return {"current_streak": 0, "max_streak": 0} max_streak = 1 current_sequence = 1 # 遍历计算所有连续段的长度,更新最长连续天数 for i in range(1, len(created_dates)): prev_date = created_dates[i-1] curr_date = created_dates[i] if curr_date == prev_date + timedelta(days=1): current_sequence += 1 if current_sequence > max_streak: max_streak = current_sequence else: current_sequence = 1 # 计算当前连续天数 today = date.today() last_date = created_dates[-1] current_streak = 0 # 获取最后一个连续段的长度 last_sequence_length = 1 for i in range(len(created_dates)-1, 0, -1): if created_dates[i] == created_dates[i-1] + timedelta(days=1): last_sequence_length += 1 else: break # 判断最后连续段是否延续至今日 if last_date == today: current_streak = last_sequence_length return {"current_streak": current_streak, "max_streak": max_streak}
边界情况处理
- 用户无任何分类创建记录:返回
{"current_streak": 0, "max_streak": 0}; - 用户仅在单日创建分类:若当日为今日则
current_streak=1,否则为0,max_streak=1; - 用户存在多段不连续的创建记录:自动统计最长的连续段作为
max_streak。
内容的提问来源于stack exchange,提问作者lord stock
相关产品推荐
相关产品推荐

