Home > Software design >  annotate model with aggregate state of manytomany field
annotate model with aggregate state of manytomany field

Time:10-20

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()
    )
)
  • Related