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

如何用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
}

实现方案

核心思路

  1. 提取用户创建分类的所有唯一日期(仅保留日期部分)并按时间升序排列;
  2. 遍历日期列表,统计所有连续日期段的长度,找出最长段作为max_streak;
  3. 检查最后一个连续段是否延续至今日,确定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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 05:03:21