2010-05-20 4 views
4

У меня есть две модели, авторы и статьи:Джанго и условные агрегаты

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's aggregates. Проблема в том, что она должна учитывать только статьи, которые уже опубликованы. Согласно ticket 11305 в трекер-путеводителе Django, это еще не возможно. Я попытался использовать аннотацию CountIf, упомянутую в этом билете, но он не цитирует строку datetime и не делает все необходимые ей соединения.

Итак, какое лучшее решение, кроме написания собственного SQL?

ответ

3

Джанго 1.8+ решение

Поскольку Django 1.8, conditional expressions доступны для строительства querysets.

Для получения более подробной информации обратитесь к документации, но быстрое решение для Вашего вопроса будет выглядеть примерно так:

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

Я не проверял это, хотя, но он должен работать.

1

я решил мою проблему, создав представление SQL с необходимым GROUP BY заявления и моделью для указанного вида с managed = False и OneToOneField к Author таблице. Это не самое эффективное или элегантное решение, но оно работает хорошо.

5

Вы можете использовать приложение django-aggregate-if, вдохновленное ticket 11305. Или вы можете просто использовать метод extra для QuerySet (предположим, что ваш приложение с именем "статьи"):

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-aggregate-if работал как шарм! – jobima

Смежные вопросы