Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django and conditional aggregates

I have two models, authors and articles:

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)

Now I want to select all authors and annotate them with their respective article count. That's a piece of cake with Django's aggregates. Problem is, it should only count the articles that are already published. According to ticket 11305 in the Django ticket tracker, this is not yet possible. I tried to use the CountIf annotation mentioned in that ticket, but it doesn't quote the datetime string and doesn't make all the joins it would need.

So, what's the best solution, other than writing custom SQL?

like image 872
Benjamin Wohlwend Avatar asked Dec 29 '22 16:12

Benjamin Wohlwend


1 Answers

You could use django-aggregate-if application, that inspired by ticket 11305. Or you can just use the extra method for queryset (suppose your application named "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'})
like image 71
Timofey Trukhanov Avatar answered Mar 05 '23 04:03

Timofey Trukhanov