Django исключить из числа аннотаций

У меня есть следующее приложение:

from django.db import models class Worker(models.Model): name = models.CharField(max_length=60) def __str__(self): return self.name class Job(models.Model): worker = models.ForeignKey(Worker) is_completed = models.BooleanField() 

Я хочу аннотировать запрос Workers с количеством выполненных заданий.

Я попытаюсь сделать это со следующим скриптом:

 from myapp.models import Worker, Job from django.db.models import Count w = Worker.objects.create(name='Worker1') Job.objects.create(worker=w, is_completed=False) Job.objects.create(worker=w, is_completed=False) Job.objects.create(worker=w, is_completed=True) Job.objects.create(worker=w, is_completed=True) workers = Worker.objects.all().annotate(num_jobs=Count('job')) workers[0].num_jobs # >>> 4 workers = Worker.objects.all().exclude(job__is_completed=False).annotate(num_jobs=Count('job')) # >>> [] 

Результат последнего запроса пуст. Как исключить элементы из обратного отношения?

Django 1.8, python 2.7

UPD. Я хотел бы, чтобы все рабочие в наборе запросов, даже те, у кого нулевые задания

3 Solutions collect form web for “Django исключить из числа аннотаций”

update : ok Я немного поиграл с этим, чтобы создать решение, и я думаю, что получил его с помощью условных выражений :

Условные выражения позволяют использовать if … elif … else в фильтрах, аннотациях, агрегатах и ​​обновлениях. Условное выражение оценивает ряд условий для каждой строки таблицы и возвращает выражение результата сопоставления.

Примечание. Условные выражения (например, Case и When ) являются новыми в Django 1.8 , как указано @Pynchia

 from django.db.models import IntegerField, Sum, Case, When workers = Worker.objects.annotate( num_jobs=Sum( Case( When(job__is_completed=True, then=1), default=0, output_field=IntegerField() ) ) ) по from django.db.models import IntegerField, Sum, Case, When workers = Worker.objects.annotate( num_jobs=Sum( Case( When(job__is_completed=True, then=1), default=0, output_field=IntegerField() ) ) ) 

теперь у каждого работника будет num_jobs, который будет Integer, который показывает, сколько заполненных заданий у рабочего есть 🙂

Следующие

 workers = Worker.objects.filter(job__is_completed=True)).annotate(num_jobs=Count('job__is_completed')) 

аннотирует тех работников, у которых есть хотя бы одна работа. Те, у которых количество нулевых заданий завершено, не включены в набор запросов результатов.

Если вы хотите, чтобы все работники появлялись в наборе запросов результатов, было бы здорово, если бы мы могли написать

 workers = Worker.objects.annotate(num_jobs=CountIf('job__is_completed', job__is_completed=True)) 

но, к сожалению, мы не можем. Поэтому я не в своей глубине, и я считаю, что мой ответ является частичным. Я приветствую вмешательство кого-то более компетентного, чем я, кто может пролить свет на этот вопрос.

Для справки см. Эту предложенную Django функцию (закрытую)

и этот SO QA

UPDATE: Django 1.8 ввел условные выражения. @ Ответ BogdiG использует такие новые операторы для решения проблемы. Престижность!

Обновить

Если вам нужен счет завершенной работы для каждого работника, мы можем использовать подзапрос через .extra() :

 Worker.objects.extra(select={'jobs_done': 'SELECT COUNT(*) FROM {job_tbl} WHERE worker_id = {worker_tbl}.id AND is_completed' .format(worker_tbl=Worker._meta.db_table, job_tbl=Job._meta.db_table)}) 

SUM(CASE WHEN is_completed = True THEN 1 ELSE 0 END) что Django теперь поддерживает отображение Python условного выражения SUM(CASE WHEN is_completed = True THEN 1 ELSE 0 END) в синтаксисе, описанном в ответе @ BogdiG .


Убраны вещи о filter/exclude

  • Как добавить фильтры в запрос динамически в Django?
  • Django copy / paste Queryset
  • Model.objects.create эквивалент, который выполняет full_clean?
  • Метод модели Django - create_or_update
  • Django: условное выражение
  • Когда Django просматривает первичный ключ внешних ключей?
  • Django - несколько DB + несколько моделей
  • Самостоятельный внешний ключ Django
  • Как рекурсивно запрашивать в django эффективно?
  • Оптимизация запросов к базе данных в структуре Django REST
  • Как реализовать последователей / следующих в Django
  •  
    Interesting Posts for Van-Lav

    Неразрешенный атрибут reference 'objects' для класса '' в PyCharm

    Быстро добавьте значение в список

    Получить список номеров в качестве ввода от пользователя

    Является ли PyOpenGL хорошим местом для начала обучения программированию opengl?

    Как перечислить загруженные ресурсы с помощью Selenium / PhantomJS?

    не удалось вызвать firefox из селена в python на машине AWS

    Удалить перенос новой строки / возврата в файл

    Построение нескольких строк с помощью блока данных pandas

    Поддерживает ли urllib2 в Python 2.6.1 прокси-сервер через https

    Прочитайте несколько файлов csv и добавьте имя файла в качестве нового столбца в пандах

    Как вызвать методы на объектах дескриптора класса Python?

    Входной сигнал функции () в pyspark

    Почему распаковка этого объекта объекта карты «должна быть итерабельна, а не карта»?

    Изменение списка в python путем передачи его функции

    Python NLTK: триграммы триграмм Bigrams

    Python - лучший язык программирования в мире.