I'm using Django to write a social networking application, and need to implement a feature similar to the Facebook "Mutual Friends" concept. I have a simple model like this:
class Friend(models.Model):
user = models.ForeignKey(User)
guid = models.BigIntegerField()
name = models.TextField()
class Meta:
unique_together = ['user', 'facebook_id']
It represents a relationship between a user of my site, and one of his friends. (The friends are not necessarily also users) The number of mutual friends between two users can be calculated as the intersection of their friend lists, in other words,
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()
(A more efficient way of doing the above will score bonus points).
My main question is, having calculated the number of mutual friends between the users, how can I now order the users
queryset according to number of mutual friends of the current user? I cannot, in this case, save the count as a annotation or extra field, since it relies on the specific user being examined and only a certain subset of his total friends. Can I use the annotate
or extra
methods in some ingenious way? Or is a raw
sql query the only way to go? If so, how?
To summarize:
Calculating the number of mutual friends for each user is not the problem. Given that information for each user, how do you then proceed to order the QuerySet
according to that number?