В Django, как фильтровать _set внутри цикла for?
У меня есть эти две модели:
class Convocacao(models.Model):
cursos = models.ForeignKey(Cursos)
class RegistroConvocacao(models.Model):
convocacao = models.ForeignKey(Convocacao)
Я получаю конкретный объект от Convocacao:
obj = get_object_or_404(
Convocacao.objects.prefetch_related("cursos", "registroconvocacao_set"),
pk=pk,
)
Теперь, пока цикл for проходит через obj.cursos, мне нужно отфильтровать obj.registroconvocacao_set внутри цикла:
for curso in obj.cursos.all():
obj.registroconvocacao_set.filter(...filters...)...
Однако в каждой итерации цикла for, obj.registroconvocacao_set.filter() делает новый запрос к базе данных, порождая тысячи обращений к базе данных и повторных запросов.
Как мне выполнить предварительную выборку obj.registroconvocacao_set, чтобы избежать этого?
Вы уже предварительно сфотографировали объекты, поэтому пройдитесь по всем из них в Python, чтобы сформировать список тех, которые вам нужны. Например
todo = []
for o in obj.registroconvocacao_set.all():
if( rejection_condition):
continue
if( acceptance_condition):
todo.append(o)
continue
...
for filtered_objects in todo:
...
В простых случаях достаточно иметь простой тест в цикле, чтобы выполнить действие или нет:
for o in obj.registroconvocacao_set.all():
if( condition):
... #do stuff with o
или постижение списка
todo = [ o for o in obj.registroconvocacao_set.all() if condition ]
Да, было бы неплохо, если бы кверисеты распознавали, что то, что они фильтруют, уже было предварительно отфильтровано, чтобы они могли делать это внутри, не обращаясь к БД снова. Но они этого не делают, поэтому вам придется кодировать это самостоятельно-