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

Django获取48小时内数据的简便实现方法咨询

Hey there! Great question—let's simplify that code and get you the 48-hour hot news list you need without all the loop hassle.

First, let's break down what your original code does: it loops over the last two days, queries daily read counts, and aggregates them. But if your goal is to get the most viewed news articles in the last 48 hours (not just daily totals), we can streamline this with Django's ORM tools like annotate, Sum, and proper time filtering.

Case 1: Your News model has a direct pv field

If you're updating a pv field directly on the News model (like in your example code), this is super straightforward:

from django.utils import timezone
from django.db.models import F
from django.shortcuts import get_object_or_404, render

def newsDetailView(request, news_pk):
    # Get the news article or return 404
    news = get_object_or_404(News, id=news_pk)
    
    # Update PV atomically (avoids race conditions from concurrent requests)
    News.objects.filter(id=news_pk).update(pv=F('pv') + 1)
    
    # Calculate the cutoff time for 48 hours ago
    forty_eight_hours_ago = timezone.now() - timezone.timedelta(hours=48)
    
    # Filter news published/updated in the last 48 hours, ordered by PV descending
    # Replace `publish_time` with your actual time field (e.g., `update_time` if tracking recent views)
    forty_eight_hours_hot_news = News.objects.filter(
        publish_time__gte=forty_eight_hours_ago
    ).order_by('-pv')
    
    return render(request, "news_detail.html", {
        'news': news,
        'forty_eight_hours_hot_news': forty_eight_hours_hot_news
    })

Case 2: You're using a ReadDetail model to track views

If you're relying on a separate ReadDetail model (like your original code), we can aggregate the total PV for each news article in one query instead of looping through days:

from django.utils import timezone
from django.db.models import Sum
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404, render

def newsDetailView(request, news_pk):
    news = get_object_or_404(News, id=news_pk)
    
    # Add your existing code to create/update the ReadDetail record here
    # ...
    
    # Get the content type for the News model
    news_content_type = ContentType.objects.get_for_model(News)
    
    # Calculate 48-hour cutoff
    forty_eight_hours_ago = timezone.now() - timezone.timedelta(hours=48)
    
    # Aggregate total PV for each news article in the last 48 hours
    forty_eight_hours_hot_news = News.objects.filter(
        # Filter related ReadDetail records within the time frame
        readdetail__content_type=news_content_type,
        readdetail__date__gte=forty_eight_hours_ago.date()  # Use `datetime__gte` if your date field is a datetime type
    ).annotate(
        total_pv=Sum('readdetail__read_num')
    ).order_by('-total_pv')
    
    return render(request, "news_detail.html", {
        'news': news,
        'forty_eight_hours_hot_news': forty_eight_hours_hot_news
    })

Bonus: Simplifying your original get_two_days_read_data function

If you still need daily read count totals (e.g., for a chart), you can use Django's TruncDate to group results by day without looping:

from django.utils import timezone
from django.db.models import Sum
from django.db.models.functions import TruncDate

def get_two_days_read_data(content_type):
    forty_eight_hours_ago = timezone.now() - timezone.timedelta(hours=48)
    
    # Group read details by date and sum the read counts
    daily_read_data = ReadDetail.objects.filter(
        content_type=content_type,
        date__gte=forty_eight_hours_ago.date()
    ).annotate(
        day=TruncDate('date')
    ).values('day').annotate(
        total_read=Sum('read_num')
    ).order_by('day')
    
    # Extract dates and read numbers in your desired format
    dates = [entry['day'].strftime('%m/%d') for entry in daily_read_data]
    read_nums = [entry['total_read'] or 0 for entry in daily_read_data]
    
    return dates, read_nums

Key improvements here:

  • Single queries instead of loops: Reduces database hits and improves performance.
  • Timezone-aware filtering: Uses timezone.now() to avoid issues with time zone mismatches.
  • Atomic updates: Using F('pv') + 1 ensures PV counts stay accurate even with multiple concurrent requests.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:38:20