I have a Stream that has permissions = ManyToManyField(Permission) Permission has a state field. If all of the state's permissions are True then annotate state with allowed=True, else annotate state with 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)]
CodePudding user response:
If I understand your question correctly, this should do it
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()
)
)