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

Django中如何统计模型对象一周内各天的检索访问总次数

实现思路

你当前的Watched模型仅存储了全局累计的访问次数,没有按天留存访问记录,无法直接回溯历史每日的统计数据,需要先调整存储逻辑,再做周维度的按天聚合,具体实现步骤如下:


步骤1:调整数据模型,新增日维度统计存储

新增WatchedDaily模型用于存储单条Watched对象每日的访问次数,不需要修改原有模型的存量逻辑:

from django.db import models
from django.utils import timezone

class Watched(Stamping):
    user = models.ForeignKey("User", null=True, blank=True, on_delete=models.CASCADE)
    count = models.PositiveIntegerField(default=0) # 原有总计数保留
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

class WatchedDaily(models.Model):
    watched = models.ForeignKey(Watched, on_delete=models.CASCADE, related_name="daily_stats")
    date = models.DateField(default=timezone.now)
    day_count = models.PositiveIntegerField(default=0)

    class Meta:
        # 确保同一个Watched对象同一天只会生成一条统计记录
        constraints = [
            models.UniqueConstraint(fields=['watched', 'date'], name='unique_watched_per_day')
        ]

步骤2:修改访问自增逻辑,同步更新总计数和当日计数

检索对象触发计数自增时,使用Django的F表达式避免竞态问题,同时更新总计数和当日统计:

from django.db.models import F
from django.utils import timezone

# 你原有检索Watched对象的逻辑中,触发count自增的部分替换为以下代码
# 假设当前检索到的对象为watched_obj
today = timezone.now().date()

# 当日计数自增,不存在则自动创建记录
WatchedDaily.objects.update_or_create(
    watched=watched_obj,
    date=today,
    defaults={"day_count": F("day_count") + 1}
)
# 原有总计数同步自增
watched_obj.count = F("count") + 1
watched_obj.save(update_fields=["count"])

步骤3:按周聚合查询,生成要求格式的统计结果

查询指定对象最近7天的统计数据,转换为以星期缩写为键的字典:

from django.utils import timezone
from datetime import timedelta

WEEK_DAY_MAP = {
    0: "Mon", 1: "Tue", 2: "Wed", 3: "Thu",
    4: "Fri", 5: "Sat", 6: "Sun"
}

def get_watched_weekly_stats(watched_obj):
    end_date = timezone.now().date()
    start_date = end_date - timedelta(days=6) # 包含首尾共7天
    # 查询时间范围内的所有日统计记录
    daily_records = WatchedDaily.objects.filter(
        watched=watched_obj,
        date__range=(start_date, end_date)
    )
    # 组装结果
    stats = {}
    for record in daily_records:
        week_day_num = record.date.weekday()
        stats[WEEK_DAY_MAP[week_day_num]] = record.day_count
    return stats

调用get_watched_weekly_stats(WatchedObject1)即可得到你需要的{'Sun': 10, 'Tue': 70, 'Wed': 35}格式的结果。

注意:如果你没有存储历史的日访问日志,调整模型前的历史日统计数据无法回溯,只能从调整上线当日开始统计。


内容的提问来源于stack exchange,提问作者Sammy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:57:02