from datetime import datetime, time, timedelta from django.utils import timezone from tracker.models import DailyStat, Event, VisitSession, Visitor def refresh_daily(site, date) -> DailyStat: """重算某站点某自然日的聚合(幂等,update_or_create)。 日界取 TIME_ZONE(Asia/Shanghai)自然日:make_aware(datetime.combine(date, time.min))。 口径:pv/uv 均从事件表统计(排除 is_bot),uv=distinct visitor,与 pv 同源; sessions 按会话 started_at 落入当日且访客非爬虫;new_visitors 按 Visitor.first_seen_at 落入当日(同样排除爬虫访客,四指标口径统一)。 """ day_start = timezone.make_aware(datetime.combine(date, time.min)) day_end = day_start + timedelta(days=1) pv = Event.objects.filter(site=site, is_bot=False, occurred_at__gte=day_start, occurred_at__lt=day_end).count() uv = Event.objects.filter(site=site, is_bot=False, occurred_at__gte=day_start, occurred_at__lt=day_end).values("visitor").distinct().count() sessions = VisitSession.objects.filter(site=site, visitor__is_bot=False, started_at__gte=day_start, started_at__lt=day_end).count() new_v = Visitor.objects.filter(site=site, is_bot=False, first_seen_at__gte=day_start, first_seen_at__lt=day_end).count() obj, _ = DailyStat.objects.update_or_create(site=site, date=date, defaults={"pv": pv, "uv": uv, "sessions": sessions, "new_visitors": new_v}) return obj