Django - 用多个计数进行注释

2023-12-31

我有一个模型叫Post它有两个字段upvotes and downvotes. Now, upvotes, downvotes are ManyToManyField to a Profile。这是模型:

class Post(models.Model):
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
    title = models.CharField(max_length=300)
    content = models.CharField(max_length=1000)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    subreddit = models.ForeignKey(Subreddit, on_delete=models.CASCADE)
    upvotes = models.ManyToManyField(Profile, blank=True, related_name='upvoted_posts')
    downvotes = models.ManyToManyField(Profile, blank=True, related_name='downvoted_posts')

所以,我想获取所有帖子,使其按以下顺序排列

total(upvotes) - total(downvotes)

所以我使用了这个查询:

Post.objects.annotate(
    total_votes=Count('upvotes')-Count('downvotes')
).order_by('total_votes')

这个查询的问题是total_votes总是结果是zero.

以下查询将解释这种情况:

In [5]: Post.objects.annotate(up=Count('upvotes')).values('up')
Out[5]: <QuerySet [{'up': 1}, {'up': 3}, {'up': 2}]>

In [6]: Post.objects.annotate(down=Count('downvotes')).values('down')
Out[6]: <QuerySet [{'down': 1}, {'down': 1}, {'down': 1}]>

In [10]: Post.objects.annotate(up=Count('upvotes'), down=Count('downvotes'), total=Count('upvotes')-Count('downvotes')).values('up', 'down', 'total')
Out[10]: <QuerySet [{'up': 1, 'down': 1, 'total': 0}, {'up': 3, 'down': 3, 'total': 0}, {'up': 2, 'down': 2, 'total': 0}]>

看起来两个都像up and down具有相同的值(实际上是up)。我该如何解决这个问题?

我已经尝试过这个:

In [9]: Post.objects.annotate(up=Count('upvotes')).annotate(down=Count('downvotes')).values('up', 'down')
Out[9]: <QuerySet [{'up': 1, 'down': 1}, {'up': 3, 'down': 3}, {'up': 2, 'down': 2}]>

但即使这样也给出了相同的输出。


尝试使用dictinct https://docs.djangoproject.com/en/2.1/topics/db/aggregation/#combining-multiple-aggregations争论:

Post.objects.annotate(
    total_votes=Count('upvotes', distinct=True)-Count('downvotes', distinct=True)
).order_by('total_votes')

来自文档:

将多个聚合与 annotate() 结合起来会产生错误 结果是因为使用连接而不是子查询。对于大多数 聚合,没有办法避免这个问题,但是,Count 聚合有一个可能有帮助的独特参数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django - 用多个计数进行注释 的相关文章

随机推荐