Django: подсчет вложенных реверсов Foreignkey
мои модели:
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)
Теперь я хочу узнать, если менее 5 подразделов курса являются registration_required = False
. что-то вроде:
def validate(self, attrs):
course = self.instance
if course.sections.subsections.filter(registration_required=False).count() < 5:
# do something ...
как лучше это сделать?
a = Course.objects.get({something})
Course.objects.filter(pk=a.pk, section__subsection__registration_required=False).count()
Вы можете проверить наличие одного Course
объекта course
с помощью:
Subsection.objects.filter(
registration_required=False, section__course=my_course
).count() < 5
или с агрегатом:
from django.db.models import Count, Q
my_course.sections.aggregate(
total=Count(
'subsections',
filter=Q(subsections__registration_required=False),
)
)['total'] < 5
Если вы хотите сделать это в большом количестве, используйте:
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)
Таким образом, сначала мы подсчитываем количество SubSection
с registration_required=False
, а затем отфильтровываем Course
на это число (nsubsec
) так, чтобы оно было меньше пяти.
Попробуйте это
def validate(self, attrs):
course = self.instance
# Count the number of SubSections with registration_required=False for the given course
count = SubSection.objects.filter(
section__course=course,
registration_required=False
).count()
if count < 5:
# Do something if fewer than 5 SubSections have registration_required=False
pass
return attrs