2015-11-26 58 views
0

說我有兩個模式是這樣的:與信息標註的queryset

from django.contrib.auth import User 

class Post(models.Model): 
    text = models.TextField() 

class Like(models.Model): 
    post = models.ForeignKey(Post) 
    user = models.ForeignKey(User) 

非常標準,我猜。用戶可以喜歡的帖子列表。 我想要獲得所有Post對象的查詢集,如果當前用戶(認爲request.user)已經喜歡或不喜歡,用信息註釋。

像這樣的東西(當然這是不正確的)

qs = Post.objects.all().annotate(like__user=request.user) 

我要遍歷和QS有一個屬性說,如果當前用戶喜歡的崗位,這樣的事情:

for post in qs: 
    if post.current_user_liked: 
    # do something 

我想使用註釋的原因當然是性能,我想避免對每個帖子進行查詢以檢查Like with user = request.user是否存在。

回答

1

我結束了一個更簡單的方法,因爲我在分頁中顯示我的視圖中的Post對象,所以我的Postqueryset總是很小。 另外,我顯示Post由pk排序的對象。

所以我的溶液建築Post主鍵是request.user喜歡,從我目前的職位顯示選擇Python列表(所以列表總是會相當小):

pks = [ post.pk for post in queryset ] 
first = pks[0] 
last = pks[-1] 
context['liked_posts'] = Like.objects.filter(user=request.user, 
    post_id__range=sorted([first, last])).values_list('post_id', flat=True) 

然後在我的模板我只是檢查每個Post包是否在liked_posts列表中。

這種方法只需要對數據庫進行額外查詢。

3

我認爲你可以使用annotate()RawSQL爲此。

如果這不起作用,您可以將prefetch_relatedPrefetch對象一起使用,以便Django通過一個額外的查詢加載所有相關的喜歡。

Post.objects.all().prefetch_related(
    Prefetch('current_user_likes', queryset=Like.objects.filter(user=request.user)) 
) 

然後,你遍歷查詢集,你會怎麼做:

for post in qs: 
    if post.current_user_likes.all(): 
     # do something 

請注意,您使用的all()這裏,因爲結果已經被取出。如果你不需要結果,通常exists()會更高效,但是在這裏會引起額外的查詢。

+0

我最終以一種更簡單的方法解決了這個問題,當我的方法不可行時,我會爲您的未來提出建議。非常感謝你! – baxeico