Аннотировать модель совокупным состоянием поля manytomany

У меня есть Stream, который имеет разрешения = ManyToManyField(Permission). Разрешение имеет поле state. Если все разрешения состояния равны True, то аннотируйте состояние с allowed=True, иначе аннотируйте состояние с allowed=False

from django.db import models

class Permission(models.Model):
    name = models.CharField(max_length=10),
    state = models.BooleanField()

class Stream(models.Model):
    permissions = models.ManyToManyField(Permission)

p1 = Permission.objects.create(state=True)
p2 = Permission.objects.create(state=False)
s = Stream.objects.create(name='s')
s.permissions.add([p1, p2])
s1 = Stream.objects.create(name='s1')
s1.permissions.add(p1)
s2 = Stream.objects.create(name='s2')
s2.permissions.add(p2)

# How can I do something like this?
annotated_streams = Stream.objects.annotate(allowed={... all([p.state for p in permissions]) ...})

[(s.name, s.allowed) for s in annotated_streams]

[('s', False), ('s1', True), ('s2', False)]

Если я правильно понимаю ваш вопрос, это должно сделать это

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

annotated_streams = Stream.objects.alias(
    fcount = Count('permissions', filter=(Q(permissions__state=False)),
).annotate(
    allowed = Case(
        When(Q(fcount__gt=0), then=False)
        default = True, output_field=BooleanField()
    )
)
Вернуться на верх