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

Django中统计每个用户的好友数量并按降序展示的方法

如何高效统计用户的好友数量并降序展示?

嘿,我来帮你搞定这个高效统计的问题!首先先明确你的场景:现有Friend模型定义如下:

class Friend(models.Model):
    to_friend = models.ForeignKey(User)
    from_friend = models.ForeignKey(User, related_name='owner')

你当前的实现方式是循环每个用户然后单独统计,代码如下:

for user in User.objects.all():
    user.friend_set.all().count()

确实,这种方式效率很低——因为每循环一个用户就会发起一次数据库查询,N个用户就会产生N+1次查询(初始的User.objects.all()是1次,每个count()又是1次),也就是大家常说的N+1查询问题,用户量一大就会拖慢系统。

下面给你两种更高效的实现思路,都是把统计工作交给数据库来做,只需要一次查询就能搞定:


1. 统计单向好友数量(比如别人添加当前用户为好友的数量)

如果你的“好友”定义是被他人添加的数量(对应你原来代码中user.friend_set.count()的逻辑),可以用Django的annotate结合Count聚合函数:

from django.db.models import Count

# 一次性统计所有用户的好友数量,并按数量降序排列
user_friend_stats = User.objects.annotate(
    friend_count=Count('friend_set')
).order_by('-friend_count')

# 遍历结果使用,每个user对象会多出friend_count属性
for user in user_friend_stats:
    print(f"用户 {user.username} 的好友数:{user.friend_count}")

为什么高效?

Django会自动生成包含COUNT聚合的SQL语句,让数据库直接完成统计和排序,全程只需要一次数据库请求,相比循环查询的方式,性能提升非常明显,尤其是用户量较大的时候。


2. 统计双向好友数量(发起+被加的总好友数)

如果你的“好友”定义是双向的——既包括当前用户添加的好友,也包括添加当前用户的好友,可以结合Q表达式或者直接合并两个反向关联的统计:

from django.db.models import Count, Q

# 方式1:直接合并两个关联的统计结果
user_total_friends = User.objects.annotate(
    total_friends=Count('friend_set') + Count('owner')
).order_by('-total_friends')

# 方式2:用Q表达式过滤后统计(适合需要去重的场景)
user_total_friends = User.objects.annotate(
    total_friends=Count('id', filter=Q(friend_set__isnull=False) | Q(owner__isnull=False), distinct=True)
).order_by('-total_friends')

注意点:

如果Friend模型中存在重复的好友记录(比如同一个用户多次添加对方为好友),记得在Count里加上distinct=True来去重,比如:

# 统计被加好友数量时去重(避免同一个用户多次添加导致统计重复)
user_friend_stats = User.objects.annotate(
    friend_count=Count('friend_set__from_friend', distinct=True)
).order_by('-friend_count')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:27:37