2010-05-20 78 views
4

我有兩個型號,作者和文章:Django和有條件的聚集

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其他?

回答

3

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

我沒有檢查它雖然,但它應該工作。

1

我通過創建一個具有所需GROUP BY聲明,並與managed = False說視圖模型和OneToOneFieldAuthor表中的SQL視圖解決我的問題。這不是最高效或優雅的解決方案,但它可以正常工作。

5

你可以使用django-aggregate-if應用程序,通過ticket 11305啓發。 或者你可以只使用extra方法查詢集(假設應用程序名爲 「文章」):

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'}) 
+0

Django的聚集型,如果工作就像一個魅力! – jobima 2016-07-13 08:52:08