Django 用 related_name 从 A->C 注释,其中 A->B 和 B->C 其中 '->' 是反向关系

Django annotate with related_name from A->C where A->B and B->C where '->' is reverse relationship

我在网上搜索了很多,但没有找到类似的问题。

我有 3 个模型:DomainTopicPost 每个 Domain 可以有很多 Topics,每个 Topic 可以有很多 Posts.

Topicforeign keyDomainPostforeign keyTopic

所以我可以通过 annotate(Count('posts'))Topic 中包含 count of Posts 我可以通过 annotate(Count('topics'))

Board 中包含 count of Topics

有什么方法可以通过 annotateBoard 中包含 count of Posts 吗?

是的,你可以使用双下划线(__)来查看关系:

from django.db.models import Count

Domain.objects.annotate(
    <b>num_posts=Count('topics__posts')</b>
)

如果将此与计算 Topic 的数量相结合,则需要将 distinct=True 添加到 TopicCount,因为这将制作两个 JOINs,JOINPosts 上将充当“乘数”:

from django.db.models import Count

Domain.objects.annotate(
    num_posts=Count('topics__posts'),
    num_topics=Count('topics'<b>, distinct=True</b>)
)

这将导致如下查询:

SELECT domain.*
       COUNT(post.id) AS num_posts
       COUNT(DISTINCT topic.id) AS num_topics
FROM domain
LEFT OUTER JOIN topic ON topic.domain_id = domain.id
LEFT OUTER JOIN post ON post.topic_id = topic.id
GROUP BY domain.id

如果您省略了 distinct=True,同一个主题将被计算 多次 次(与该主题相关的帖子数完全相同主题),因此 num_topics 应该与 num_posts 相同。通过使用 DISTINCT,我们计算每个组中 唯一 个主题的数量。