【问题标题】:Django Count() in multiple annotations多个注释中的 Django Count()
【发布时间】:2011-10-11 07:58:58
【问题描述】:

假设我有一个简单的论坛模型:

class User(models.Model):
    username = models.CharField(max_length=25)
    ...

class Topic(models.Model):
    user = models.ForeignKey(User)
    ...

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

现在假设我想查看用户子集的每个用户有多少主题和帖子(例如,他们的用户名以“ab”开头)。

因此,如果我对每个帖子和主题进行一次查询:

User.objects.filter(username_startswith="ab")
            .annotate(posts=Count('post'))
            .values_list("username","posts")

产量:

[('abe', 5),('abby', 12),...]

User.objects.filter(username_startswith="ab")
            .annotate(topics=Count('topic'))
            .values_list("username","topics")

产量:

[('abe', 2),('abby', 6),...]

但是,当我尝试同时注释两者以获得一个列表时,我得到了一些奇怪的东西:

User.objects.filter(username_startswith="ab")
            .annotate(posts=Count('post'))
            .annotate(topics=Count('topic'))
            .values_list("username","posts", "topics")

产量:

[('abe', 10, 10),('abby', 72, 72),...]

为什么主题和帖子会成倍增加?我预料到了:

[('abe', 5, 2),('abby', 12, 6),...]

获得正确列表的最佳方法是什么?

【问题讨论】:

    标签: django annotations count django-queryset


    【解决方案1】:

    我认为Count('topics', distinct=True) 应该做正确的事。这将使用COUNT(DISTINCT topic.id) 而不是COUNT(topic.id) 以避免重复。

    User.objects.filter(
        username_startswith="ab").annotate(
        posts=Count('post', distinct=True)).annotate(
        topics=Count('topic', distinct=True)).values_list(
        "username","posts", "topics")
    

    【讨论】:

    【解决方案2】:

    尝试向您的最后一个查询集添加 distinct:

    User.objects.filter(
        username_startswith="ab").annotate(
        posts=Count('post')).annotate(
        topics=Count('topic')).values_list(
        "username","posts", "topics").distinct()
    

    有关更多详细信息,请参阅https://docs.djangoproject.com/en/1.3/ref/models/querysets/#distinct,但基本上你会得到重复的行,因为注释跨越多个表。

    【讨论】:

    • 我有类似的问题,但添加distinct 似乎没有帮助。文档对distinct() 和 ordering 之间的交互有警告,但我检查了我的输出 SQL 并验证没有指定 order。
    • 您提到的原因是正确的,但独特的必须去其他地方(请参阅接受的答案)。
    猜你喜欢
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 2019-01-13
    • 2018-06-01
    • 1970-01-01
    • 2014-11-13
    • 2021-11-04
    相关资源
    最近更新 更多