在Django中按M2M字段注释值和组

时间:2013-10-31 13:24:01

标签: python database django

在下面的(超简化)代码中,函数get_top_authors()为我提供了作者列表,每个作者都有已发表文章的数量,从作者中排序最多,文章最少,作者文章最少,函数get_articles_per_year()为我提供了每年为整个数据库发布的文章总数列表。

如果我想要每个N作者(或者只是前5名)每年的文章数量,我可以重新查询N(或5)次。但是,有没有更有效的方法呢?

from django.db import models

class Author:
    name = models.TextField()

class Article:
    author = models.ManyToManyField(Author)
    year = models.IntegerField()

def get_top_authors():
    top_authors = Author.objects.all() \
        .annotate(articles=models.Count('article')).order_by('-articles')

def get_articles_per_year():
    return Article.objects.all()
        .values('year').order_by('year') \
        .annotate(articles=models.Count('year'))

1 个答案:

答案 0 :(得分:0)

以下是我在阅读之后得出的答案:

articles_per_author_per_year = Article.objects.all() \
    .values('year', 'authors_name').order_by('year')\
    .annotate(articles=models.Count('id'))

诀窍是annotate之后values聚合在由值参数的唯一排列形成的组之上。在这种情况下,这意味着它将每年为每位作者添加所有文章。该语句简化为在M2M表上使用LEFT OUTER JOIN的一个查询,而不是每个作者的N个查询。