【问题标题】:DRF annotate Count on many-to-many through table gives more occurrences than when you use _set.all().count()DRF annotate Count on many-to-many through table 比使用 _set.all().count() 时出现的次数更多
【发布时间】:2018-01-12 16:04:09
【问题描述】:

我有这些模型:

class Topic(BaseModel):

    name = models.CharField(max_length=60)
    public_name = models.CharField(max_length=60, blank=True, null=True)

class Content(BaseModel):

    title = models.CharField(max_length=120)
    series = models.CharField(max_length=120, blank=True, null=True)
    season = models.CharField(max_length=45, blank=True, null=True)
    episode = models.CharField(max_length=45, blank=True, null=True)
    tags = models.ManyToManyField(tags_models.Tag, through='ContentHasTags')
    topics = models.ManyToManyField(topics_models.Topic, through='ContentHasTopics')

class ContentHasTopics(BaseModel):

    content = models.ForeignKey(Content)
    topic = models.ForeignKey(topics_models.Topic)

    order = models.IntegerField(default=99)

    class Meta:
        unique_together = ('content', 'topic',)
        ordering = ('order',)

我遇到的问题是,如果我使用下一个函数:

@property
def get_contents_count(self):
    return self.contenthastopics_set.all().count()

在许多情况下,我有 7 个结果(并且是真的),但是当我对 Django Rest Framework(在视图集中)使用这样的注释查询时,它给了我 28 个结果,其他一些主题有 5 个内容使用 _set.all().count(),但 annotate 结果给我 10,依此类推。

queryset = models.Topic.objects.all().annotate(
    themes_count=Count('themehastopics')
).annotate(
    contents_count=Count('contenthastopics')
).annotate(
    tags_count=Count('topichastags')
)

正确添加 Count 的查询注释的正确方法是什么?

【问题讨论】:

  • 使用 distinct 可以解决问题,在具有一对/多对多关系的相关表上使用注释会由于表连接而重复结果。如果你使用 postgreSQL,你甚至可以将参数传递给 distinct()。
  • 感谢 Azee,我看了更多,发现我可以在 Count 中使用 distinct() 函数,因此使用 Count('contenthastopics', distinct=True) 可以按预期工作

标签: python django django-rest-framework


【解决方案1】:

这就是我最终解决这个问题的方法:

queryset = models.Topic.objects.all().annotate(
    themes_count=Count('themehastopics', distinct=True),
    contents_count=Count('contenthastopics', distinct=True),
    tags_count=Count('topichastags', distinct=True)
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 2016-09-05
    • 2021-09-20
    • 1970-01-01
    相关资源
    最近更新 更多