my models:
class Course(models.Model):
...
class Section(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='sections')
...
class SubSection(models.Model):
section = models.ForeignKey(Section, on_delete=models.CASCADE, related_name='subsections')
registration_required = models.BooleanField(default=True)
now I want to know if less than 5 subsections of a course are registration_required = False
. something like:
def validate(self, attrs):
course = self.instance
if course.sections.subsections.filter(registration_required=False).count() < 5:
# do something ...
what is the best way to do that ??
You can check for a single Course
object course
with:
Subsection.objects.filter(
registration_required=False, section__course=my_course
).count() < 5
or with an aggregate:
from django.db.models import Count, Q
my_course.sections.aggregate(
total=Count(
'subsections',
filter=Q(subsections__registration_required=False),
)
)['total'] < 5
If you want to do this in bulk, you use:
from django.db.models import Count, Q
Course.objects.alias(
nsubsec=Count(
'sections__subsections',
filter=Q(sections__subsections__registration_required=False),
)
).filter(nsubsec__lt=5)
Here we thus first count the number of SubSection
s with registration_required=False
, and then we filter the Course
s on that number (nsubsec
) such that it is less than five.