2017-10-18 96 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)) 
)