Python 帮助将此查询转换为Django ORM
我有一个友谊模型,其中有两个相关的用户对象。我想写一个方法,它接受一个用户并返回该用户的朋友列表。我是通过:Python 帮助将此查询转换为Django ORM,python,sql,django,orm,Python,Sql,Django,Orm,我有一个友谊模型,其中有两个相关的用户对象。我想写一个方法,它接受一个用户并返回该用户的朋友列表。我是通过: friends = Friendship.objects.filter(Q(user1=user) | Q(user2=user)) friends_list = [f.user1 if user == f.user2 else f.user2 for f in friends] 但这会导致查询集中返回的每个用户都有一个查询,例如数百个查询。我可以通过: friends = Fr
friends = Friendship.objects.filter(Q(user1=user) | Q(user2=user))
friends_list = [f.user1 if user == f.user2 else f.user2 for f in friends]
但这会导致查询集中返回的每个用户都有一个查询,例如数百个查询。我可以通过:
friends = Friendship.objects.select_related().filter(Q(user1=user) | Q(user2=user))
friends_list = [f.user1 if user == f.user2 else f.user2 for f in friends]
但这在用户表上执行内部联接。我也可以通过自定义SQL编写
friends = User.objects.raw("""
SELECT * FROM usertable WHERE id IN (SELECT
user1_id FROM friendstable WHERE user2_id=%d) OR id IN
(SELECT user2_id FROM lists_friendship WHERE user1_id=%d);
""" % (user.pk, user.pk))
但我在想,一定有一种方法可以在ORM内部完成,而无需所有额外的查找。我试图在中使用id_uu做一些事情,但是我找不到一种方法来从friends查询集中获取用户id 假设您设置的友谊模型与下面的示例类似,并使用friend_set作为模型中from_friend字段的相关名称,则获取用户朋友列表可以像基本列表理解一样简单:
friends = [friendship.to_friend for friendship in user.friend_set.all()]
这甚至允许您访问模板中用户的好友,而无需将其作为变量传递:
{% for friendship in user.friend_set.all %}
{{ friendship.to_friend.username }}
{% endfor %}
您的友谊模型如下所示:
class Friendship(models.Model):
from_friend = models.ForeignKey(
User, related_name='friend_set'
)
to_friend = models.ForeignKey(
User, related_name='to_friend_set'
)
def __unicode__(self):
return u'%s, %s' % (
self.from_friend.username,
self.to_friend.username
)
class Meta:
unique_together = (('to_friend', 'from_friend'), )
下面是一篇关于在Django中建立朋友网络的精彩文章:
请注意,您不必同时检查from\u friend和to\u friend来获取用户朋友列表。如果你有一个follow/follower友谊模型,你只需要一个from_friend=用户的所有友谊实例,如果你有一个double-opt-in友谊模型,你可以按照Facebook的做法,在被邀请的朋友接受朋友邀请后,为他们添加一个实例作为from_friend。这就是raw的目的,这样您就不会被迫在ORM中进行复杂的数据操作