2017-10-18 93 views
0

我有「後」的對象和「後像」對象有多少喜歡一個帖子已收到其用戶數:Django的:註釋與過濾

class Post(models.Model): 
    text  = models.CharField(max_length=500, default ='') 
    user  = models.ForeignKey(User) 

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

我可以選擇多少喜歡一個帖子有收到這樣的:

Post.objects.all().annotate(likes=Count('postlike')) 

這大致翻譯爲:

SELECT p.*, 
     Count(l.id) AS likes 
    FROM post p, postlike l 
    WHERE p.id = l.post_id 
    GROUP BY (p.id) 

它的工作原理。現在,我怎麼可以過濾器Count由當前用戶聚合?我想檢索不是全部喜歡的帖子,但所有喜歡由登錄用戶。產生的SQL應該是這樣的:

SELECT p.*, 
    (SELECT COUNT(*) FROM postlike WHERE postlike.user_id = 1 AND postlike.post_id = p.id) AS likes 
FROM post p, postlike l 
WHERE p.id = l.post_id 
GROUP BY (p.id) 

回答

1

這不完全是乾淨的,但你可以使用Case/When ...

posts = Post.objects.all().annotate(likes=models.Count(
    models.Case(
    models.When(postlike__user_id=user.id, then=1), 
    default=0, 
    output_field=models.IntegerField(), 
) 
)) 

和當然,你總是可以下降到.extra()甚至原始的SQL語句時,有一些你無法用語言表達通過Django ORM。

1

首先嚐試添加濾鏡:

Post.objects.filter(postlike__user=request.user).annotate(likes=Count('postlike')) 

docs

過濾器之前的註釋,所以過濾器限制考慮的對象計算註釋時。

+0

嗨,謝謝你的回答,但這並不能解決我的問題。我不希望用戶喜歡的帖子,我希望所有的帖子和每個帖子,最終,用戶喜歡的數量。 Post.objects.filter不會給我完整的帖子記錄。 – pistacchio

0

你知道Countfilter的說法嗎?

Post.objects.annotate(
    likes=Count('postlike', filter=Q(postlike__user=logged_in_user)) 
)