Django - агрегирование условных дочерних полей - PullRequest
1 голос
/ 19 января 2020

Допустим, у меня есть следующие модели. Данный Job может работать в течение нескольких дней, на нем работают несколько пользователей, и у этих пользователей могут быть установлены различные флаги (логические значения в модели):

class Job(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=128)

class JobEmployee(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    date = models.DateField()
    job = models.ForeignKey(Job, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    is_sup = models.BooleanField()
    is_mgr = models.BooleanField()
    timecard_complete = models.BooelanField()

Что я хотел бы сделать, это тянуть список идентификаторов вакансий, имен, дат и количества всех детей, детей с is_mgr==True, is_sup==True и timecard_complete==False на дату каждой работы. Таким образом, результат будет выглядеть примерно так:

        Job ID                       | Job Name |    Date    | all_users | mgr | sup | missing_tc
--------------------------------------------------------------------------------------
978294d8-3ae8-11ea-b77f-2e728ce88125 |    Job 1 | 2020-01-05 |         8 |   2 |   0 |          4
978294d8-3ae8-11ea-b77f-2e728ce88125 |    Job 1 | 2020-01-06 |         6 |   0 |   1 |          3
f5e87902-3ae8-11ea-b77f-2e728ce88125 |    Job 2 | 2020-01-05 |        10 |   1 |   3 |          7
f5e87902-3ae8-11ea-b77f-2e728ce88125 |    Job 2 | 2020-01-06 |         5 |   0 |   1 |          0

Как это можно сделать с помощью запроса django?

РЕДАКТИРОВАТЬ: отредактировано, чтобы ввести имя работы, как я понимаю, я мог сделать обычный агрегатный запрос только к таблице JobEmployee, но мне также нужны данные из объекта задания.

1 Ответ

2 голосов
/ 19 января 2020

Попробуйте это

from django.db.models import Count, Q

(Job.objects.values('id', 'name', 'jobemployee__date')
.annotate(all_users=Count('jobemployee'))
.annotate(mgr=Count('jobemployee__is_mgr', filter=Q(jobemployee__is_mgr=True)))
.annotate(sup=Count('jobemployee__is_sup', filter=Q(jobemployee__is_sup=True)))
.annotate(missing_tc=Count('jobemployee__timecard_complete', filter=Q(jobemployee__timecard_complete=False))))

Не можете проверить это без вашей структуры, скажите мне, если я опечатался с ) или что-то в этом роде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...