Джанго комментирует логическое поле - PullRequest
1 голос
/ 12 апреля 2019
class Forecast(Model):
  id = UUID()
  type = StringField()
  approved = BooleanField()

Я хочу сгруппировать в поле type, применяя «логическое и» в утвержденном поле. Предположим, аннотированное поле all_approved. all_approved должно быть True, если все элементы с этим типом True, и false, если, по крайней мере, один False.

Итак, наконец, в моем наборе запросов я хочу иметь два поля type, all_approved.

Как мне этого добиться?

Я попробовал что-то на основании этого ответа , но ничего не смог получить.

EDIT:

когда я попробовал то, что дано в этом ответе, он не делал «логично и». Вместо этого для каждого type он просто дает два элемента, один с all_approved как True, другой с all_approved как False. Я хочу один элемент для каждого type.

Также я не понимаю, почему этот ответ должен работать. Где это указано, если при группировке должно выполняться «логическое и» или «логическое или».

Ответы [ 2 ]

3 голосов
/ 12 апреля 2019

другое решение: вы можете попробовать сравнить все approved с approved=True

from django.db.models import Count, Case, When, BooleanField

Forecast.objects.values(
    'type'
).annotate(
    cnt_app=Count(Case(When(approved=True, then=1)))
).annotate(
    all_approved=Case(
        When(cnt_app=Count('approved'), then=True),
        default=False,
        output_field=BooleanField()
   )
).values('type', 'all_approved')

, где

Count(Case(When(approved=True, then=1))) дает нам количество утвержденных со статусом True для типа,

Count('approved') дает нам общее количество всех для типа,

и если значения равны, тогда all_approved равно True, иначе False

2 голосов
/ 12 апреля 2019

Вы можете использовать подзапрос, чтобы перевернуть all_approved в False для типов, которые имеют хотя бы одно значение False:

from django.db.models import BooleanField
from django.db.models.expressions import Case, When

(Forecast.objects
    .annotate(all_approved=Case(
        When(type__in=Forecast.objects.filter(approved=False).values('type'), 
             then=False),
        default=True,
        output_field=BooleanField()
    ))
    .values('type', 'all_approved')
    .distinct()
)

вопрос , который вы связалинемного отличается, потому что это относится к отношениям «один ко многим» между двумя моделями, к которым автоматически присоединяется Django.

Здесь у вас есть только одна модель, к которой вам нужно присоединиться, чтобы использоватьтакое же решение.Так как Django поддерживает только объединения, определенные отношениями, вам нужно использовать подзапрос в качестве обходного пути.

...