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
相关产品推荐
相关产品推荐

