【问题标题】:Django and conditional aggregatesDjango 和条件聚合
【发布时间】:2010-05-20 15:15:38
【问题描述】:

我有两个模型、作者和文章:

class Author(models.Model):
    name = models.CharField('name', max_length=100)

class Article(models.Model)
    title = models.CharField('title', max_length=100)
    pubdate = models.DateTimeField('publication date')
    authors = models.ManyToManyField(Author)

现在我想选择所有作者并用他们各自的文章计数来注释他们。这对 Django 的aggregates 来说是小菜一碟。问题是,它应该只计算已经发表的文章。根据 Django 票务跟踪器中的ticket 11305,这还不可能。我尝试使用该票证中提到的CountIf 注释,但它没有引用日期时间字符串,也没有进行它需要的所有连接。

那么,除了编写自定义 SQL 之外,最好的解决方案是什么?

【问题讨论】:

    标签: python django aggregate


    【解决方案1】:

    您可以使用受ticket 11305 启发的django-aggregate-if 应用程序。 或者您可以只使用 extra 方法进行查询集(假设您的应用程序名为“articles”):

    Author.objects.all().extra(
        select={'article_count': 'SELECT COUNT(*) FROM "articles_article" '
                                 'INNER JOIN "articles_article_authors" '
                                 'ON "articles_article"."id" = '
                                 '   "articles_article_authors"."article_id" '
                                 'WHERE "articles_article_authors"."author_id" = '
                                 '      "articles_author"."id" '
                                 'AND "articles_article"."pubdate" IS NOT NULL'})
    

    【讨论】:

      【解决方案2】:

      Django 1.8+ 解决方案

      从 Django 1.8 开始,conditional expressions 可用于构建查询集。

      有关更多详细信息,请参阅文档,但您的问题的快速解决方案类似于:

      today = datetime.date.today()
      authors = Author.objects.all().annotate(article_count=Sum(
          Case(When(articles__pubdate__lt=today, then=1),
               output_field=IntegerField())
      ))
      

      虽然我没有检查它,但它应该可以工作。

      【讨论】:

        【解决方案3】:

        我解决了我的问题,方法是使用所需的GROUP BY 语句创建 SQL 视图,并使用managed = FalseOneToOneFieldAuthor 表创建所述视图的模型。这不是最有效或最优雅的解决方案,但可以正常工作。

        【讨论】:

          猜你喜欢
          • 2010-11-01
          • 2018-12-04
          • 2020-05-05
          • 2020-02-27
          • 2020-06-08
          • 2019-09-14
          • 2018-09-29
          • 2019-03-05
          • 1970-01-01
          相关资源
          最近更新 更多