Django Count() 在多个注释中

发布于 2024-11-25 10:58:56 字数 1328 浏览 3 评论 0原文

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

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")

Yields:

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

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

Yields:

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

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

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

Yields:

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

Why are the topic and posts相乘一起?我预料到了这一点:

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

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

Say I have a simple forum model:

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)
    ...

Now say I want to see how many topics and posts each users of subset of users has (e.g. their username starts with "ab").

So if I do one query for each post and topic:

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

Yeilds:

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

and

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

Yields:

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

HOWEVER, when I try annotating both to get one list, I get something strange:

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

Yields:

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

Why are the topics and posts multiplied together? I expected this:

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

What would be the best way of getting the correct list?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雄赳赳气昂昂 2024-12-02 10:58:56

我认为 Count('topics',distinct=True)< /code>应该做正确的事情。这将使用 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")

I think Count('topics', distinct=True) should do the right thing. That will use COUNT(DISTINCT topic.id) instead of COUNT(topic.id) to avoid duplicates.

User.objects.filter(
    username_startswith="ab").annotate(
    posts=Count('post', distinct=True)).annotate(
    topics=Count('topic', distinct=True)).values_list(
    "username","posts", "topics")
何其悲哀 2024-12-02 10:58:56

尝试向最后一个查询集添加不同的:

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 了解更多详细信息,但基本上您会得到重复的行,因为注释跨越多个表。

Try adding distinct to your last queryset:

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

See https://docs.djangoproject.com/en/1.3/ref/models/querysets/#distinct for more details, but basically you're getting duplicate rows because the annotations span multiple tables.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文