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

Django实现筛选浏览量Top3的热门文章

解决Django筛选浏览量最高的3篇热门文章问题

根据你提供的模型代码,以下是实现筛选浏览量Top3热门文章的方案:

方案1:无需修改现有模型的查询方式

使用Django的聚合查询annotate统计每篇文章对应的HitCount记录数,再按浏览量降序排序取前3:

from django.db.models import Count

# 统计每篇文章的浏览量,按浏览量降序取前3
popular_posts = Post.objects.annotate(
    hit_count=Count('hitcount_set')
).order_by('-hit_count')[:3]

说明:

  • annotate(hit_count=Count('hitcount_set')):给每个Post实例添加一个hit_count字段,值为该文章对应的HitCount记录总数(因为HitCount的外键未设置related_name,Django默认反向关联名为模型名小写_set,即hitcount_set)。
  • order_by('-hit_count'):按hit_count降序排列,确保浏览量高的文章在前。
  • [:3]:截取前3条结果,即浏览量最高的3篇文章。

方案2:优化模型后的更简洁查询

建议给HitCount模型的post外键添加related_name,让代码更易读:

修改HitCount模型:

class HitCount(models.Model):
    ip_address = models.GenericIPAddressField()
    # 添加related_name,指定反向关联名称
    post = models.ForeignKey("Post", on_delete=models.CASCADE, related_name='hit_counts')

    def __str__(self):
        return f'{self.ip_address} => {self.post.title}'

此时查询代码可简化为:

from django.db.models import Count

popular_posts = Post.objects.annotate(
    hit_count=Count('hit_counts')
).order_by('-hit_count')[:3]

额外说明

  • 如果需要统计唯一IP的浏览次数(同一个IP多次访问只算1次),可以修改聚合方式:
    popular_posts = Post.objects.annotate(
        hit_count=Count('hit_counts__ip_address', distinct=True)
    ).order_by('-hit_count')[:3]
    
  • 避免使用你定义的get_hit_count属性进行批量查询,因为会触发N+1数据库查询(每篇文章单独查一次HitCount),性能远不如annotate的单次聚合查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:10:24