2011-07-29 39 views
1

我有一個友情模型,其中有兩個相關的用戶對象與它關聯。我想編寫一個方法,接受用戶並返回該用戶的朋友列表。我這樣做是通過:幫助將此查詢翻譯爲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 = 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] 

但是這會在用戶表上進行INNER JOIN。我也可以通過自定義SQL編寫它,但我認爲必須有一種方法可以在ORM內部完成所有這些額外的查找操作。我試圖用id__in做一些事情,但是我找不到將用戶ID從朋友查詢集中移出的方法。

+0

這就是raw()所做的,所以你不會被迫在ORM中做複雜的數據操作 – verisimilidude

回答

0

假設您建立友誼的模型類似於下面的例子,用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_friendto_friend獲得用戶的好友列表。如果你有一個follow/follower友誼模型,你只需要所有的友誼實例與from_friend = user,並且如果你有一個雙選擇友誼模型,你可以按照Facebook的做法爲被邀請的朋友添加一個實例作爲from_friend一次他們接受朋友邀請。