我正在使用Django编写社交网络应用程序,并且需要实现类似于Facebook“共同朋友”概念的功能。我有一个这样的简单模型:
class Friend(models.Model):
user = models.ForeignKey(User)
guid = models.BigIntegerField()
name = models.TextField()
class Meta:
unique_together = ['user', 'facebook_id']
它代表了我网站的用户和他的一个朋友之间的关系。 (朋友不一定也是用户)两个用户之间的共同朋友的数量可以计算为他们的朋友列表的交集,换句话说,
users = User.objects.all()
friends = Friend.objects.filter(user=request.user)
friend_ids = [f.guid for f in friends]
for user in users:
user.mutual = Friend.objects.filter(user=user, guid__in=friend_ids).count()
(更有效的方法是获得上述奖励积分)。
我的主要问题是,计算了用户之间的共同朋友数量后,我现在如何根据当前用户的共同朋友数量订购users
查询集?我在这种情况下,不能将计数保存为注释或额外字段,因为它依赖于正在检查的特定用户,并且仅依赖于他的总朋友的某个子集。我能以某种巧妙的方式使用annotate
或extra
方法吗?或者是raw
sql查询唯一的出路?如果是这样,怎么样?
总结:
计算每个用户的共同朋友数量不是问题。鉴于每个用户的信息,您如何根据该号码继续订购QuerySet
?
答案 0 :(得分:2)
不确定这是否正是您所寻找的......但
# get current users friends (assuming guid is unique for a friend?)
user_friend_guids = Friend.objects.values_list('guid', flat=True).filter(user=user)
# get Friend objects where user not current user, is in user_friend_list, group and count by user
mutual_friends = Friend.objects.values('user__username') \
.filter(guid__in=user_friend_guids).exclude(user=user) \
.annotate(number_mutual_friends=Count('user')) \
.order_by('-number_mutual_friends')
这将返回一个用户名列表,其中包含与用户共享的朋友数量,按照他们共享的数量排序。
然后在模板中:
{% for mutual_friend in mutual_friends %}
{{mutual_friend.user__username}} - {{mutual_friends.number_mutual_friends}}
{% endfor %}