我有两个模特,作者和文章:
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之外,最好的解决方案是什么?
答案 0 :(得分:5)
您可以使用受django-aggregate-if启发的ticket 11305应用程序。
或者您可以使用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'})
答案 1 :(得分:4)
自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())
))
我虽然没有检查,但它应该有用。
答案 2 :(得分:1)
我通过创建一个包含所需GROUP BY
语句的SQL视图,以及一个包含managed = False
和OneToOneField
到Author
表的视图的模型来解决我的问题。它不是最有效或最优雅的解决方案,但它可以正常工作。