Django中统计各用户Opinion数量并展示的实现方法
统计用户Opinion数量并展示方案
一、数据库层面统计(推荐)
通过Django的annotate结合Count聚合函数,直接在数据库层面完成统计,性能最优。
1. 不修改模型的实现
利用Django自动生成的反向关联名称(模型名小写+_set):
from django.contrib.auth.models import User from django.db.models import Count from django.shortcuts import render def user_opinion_stats(request): # 统计所有用户的Opinion数量,未发表过的用户计数为0 users_with_stats = User.objects.annotate(opinion_count=Count('opinion_set')) # 若只想展示有评论的用户,添加过滤条件: # users_with_stats = User.objects.filter(opinion_set__isnull=False).annotate(opinion_count=Count('opinion_set')) return render(request, 'user_stats.html', {'users': users_with_stats})
2. 优化模型(更直观)
修改Opinion模型的外键字段,自定义反向关联名称,让代码可读性更强:
class Opinion(models.Model): id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False) # 添加related_name='opinions',指定反向关联名称 users = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='opinions') books = models.ForeignKey(Book, on_delete=models.SET_NULL, null=True, blank=True) created = models.DateTimeField(auto_now_add=True) rate = models.IntegerField() description = models.TextField() # 修复__str__方法的错误 def __str__(self): username = self.users.username if self.users else '匿名用户' book_title = self.books.title if self.books else '未知书籍' return f"{username} {book_title}"
之后视图可以简化为:
users_with_stats = User.objects.annotate(opinion_count=Count('opinions'))
二、模板展示
创建模板文件user_stats.html,遍历统计后的用户数据:
<div class="user-stats"> <h2>用户评论统计</h2> <ul> {% for user in users %} <li> <span>用户名:{{ user.username }}</span> <span>邮箱:{{ user.email }}</span> <span>评论数量:{{ user.opinion_count }}</span> </li> {% empty %} <li>暂无用户评论数据</li> {% endfor %} </ul> </div>
三、不推荐的实现方式
避免在模板中直接调用{{ user.opinion_set.count }},这种方式会为每个用户单独触发一次数据库查询,数据量大时会导致严重的性能问题。
内容的提问来源于stack exchange,提问作者gregory_000
相关产品推荐
相关产品推荐

