如何查询Django框架中Watched模型对象今日的被检索次数
实现方案
你当前定义的Watched模型中count字段为累计总计数,没有单独存储单日增量数据,无法直接查询到今日的检索次数增量,可根据你的业务需求选择以下两种实现方案:
方案1:仅需查询当日计数,无需留存历史每日数据
适合不需要回溯过往单日检索量的场景,改动最小。
步骤1:修改模型新增日期标记字段
from django.utils import timezone class Watched(Stamping): user = models.ForeignKey("User", null=True, blank=True, on_delete=models.CASCADE, default=None) count = models.PositiveIntegerField(default=0) # 新增字段,记录最后一次计数更新的日期 last_count_date = models.DateField(null=True, blank=True)
修改完成后执行python manage.py makemigrations和python manage.py migrate同步数据表结构。
步骤2:封装检索计数更新逻辑
每次用户检索对应Watched对象时调用该方法更新计数:
def update_watched_count(watched_obj): today = timezone.localdate() # 最后计数日期不是今日则重置计数为1,是今日则计数+1 if watched_obj.last_count_date != today: watched_obj.count = 1 watched_obj.last_count_date = today else: watched_obj.count += 1 # 仅更新修改的字段提升性能 watched_obj.save(update_fields=["count", "last_count_date", "updated_at"])
步骤3:查询今日检索对象及对应计数
from django.utils import timezone today = timezone.localdate() # 筛选今日有检索记录的所有对象 today_watched_list = Watched.objects.filter(last_count_date=today) for obj in today_watched_list: # obj.count 即为该对象今日的检索总次数 print(f"对象ID:{obj.id},今日检索次数:{obj.count}")
方案2:需要留存所有历史每日检索数据
适合需要回溯任意日期检索量的场景,数据结构更灵活。
步骤1:新增每日计数独立模型
from django.db import models from django.utils import timezone class WatchedDailyCount(models.Model): watched = models.ForeignKey(Watched, on_delete=models.CASCADE, related_name="daily_counts") date = models.DateField(default=timezone.localdate) daily_count = models.PositiveIntegerField(default=0) class Meta: # 保证同一个Watched对象同一天仅存在一条计数记录 constraints = [ models.UniqueConstraint(fields=["watched", "date"], name="unique_watched_date") ]
执行迁移命令同步数据表。
步骤2:封装计数更新逻辑
from django.db.models import F def update_watched_daily_count(watched_obj): today = timezone.localdate() # 存在则计数+1,不存在则创建新记录 WatchedDailyCount.objects.update_or_create( watched=watched_obj, date=today, defaults={"daily_count": F("daily_count") + 1} )
步骤3:查询今日检索对象及对应计数
from django.utils import timezone today = timezone.localdate() today_count_list = WatchedDailyCount.objects.filter(date=today).select_related("watched") for daily_item in today_count_list: print(f"对象ID:{daily_item.watched.id},今日检索次数:{daily_item.daily_count}")
补充说明:如果你不想修改原有
Watched模型,也可以新增独立的访问日志表,每次检索时写入一条带时间戳的日志记录,查询时按Watched对象ID、今日时间范围分组统计计数即可,这种方式无侵入但数据量较大时统计性能会低于上述两种方案。
内容的提问来源于stack exchange,提问作者Sammy
相关产品推荐
相关产品推荐

