membershipworks: Use EXISTS for testing flags in is_active

This behaves much more correctly, although may not have ideal performance
This commit is contained in:
Adam Goldsmith 2023-08-26 20:18:23 -04:00
parent a51f246667
commit a3a8c305ac

View File

@ -3,7 +3,7 @@ from typing import Optional
import django.core.mail.message import django.core.mail.message
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django.db.models import Q, Count, BooleanField from django.db.models import Exists, OuterRef
class Flag(models.Model): class Flag(models.Model):
@ -21,14 +21,17 @@ class Flag(models.Model):
class MemberQuerySet(models.QuerySet): class MemberQuerySet(models.QuerySet):
# TODO: maybe rename to reflect EXISTS?
@staticmethod @staticmethod
def has_flag(flag_type: str, flag_name: str): def has_flag(flag_type: str, flag_name: str):
return Count( return Exists(Flag.objects.filter(
"uid", type=flag_type,
filter=Q(flags__name=flag_name, flags__type=flag_type), name=flag_name,
output_field=BooleanField(), members=OuterRef("pk")
) ))
# TODO: it should be fairly easy to reduce the number of EXISTS by
# merging the ORed flags
def with_is_active(self): def with_is_active(self):
return self.annotate( return self.annotate(
is_active=( is_active=(