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

Interesting Posts

Слишком много файлов открываются с помощью многопроцессорной обработки.

Как установить настройки для FireFox в Robot Framework

Как сделать снимок экрана (high fps) в Linux (программирование)

Минимизировать функцию одной переменной в Tensorflow

скрипт python или bash для передачи всех файлов в папку в java-командную строку

Соответствие неправильно написанных слов с правильными в python

Поиск публичного IP-адреса в Python?

Уменьшение размера файла разброса

Оценка математического выражения (функции) для большого количества входных значений быстро

Сшивание изображений Python

Оптимизация интерпретатора в Python

как сделать легкие и эффективные графики на Python

нулевые значения массива, подлежащего преобразованию в значения nan

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

Как запрашивать хранилище данных при использовании ReferenceProperty?

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