Django filter a prefetch_related queryset
Я пытаюсь использовать prefetch_related с моделью с внешним ключом, потому что мне нужно запросить базу данных в цикле.
models.py
class SelfEvaluatedStatement(models.Model):
evaluation_statement = models.ForeignKey(EvaluationStatement, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
rating = models.IntegerField(default=0)
views.py
queryset = SelfEvaluatedStatement.objects.prefetch_related(
'evaluation_statement__sku__topic__subject', 'evaluation_statement__sku__level'
).filter(
evaluation_statement__sku__topic__subject=subject,
evaluation_statement__sku__level=level
)
for student_user in student_users:
red_count = queryset.filter(user=student_user, rating=1).count()
Однако при этом в базу данных поступает новый запрос каждый раз, когда я выполняю итерации в цикле. Возможно ли отфильтровать набор запросов, который был предварительно отфильтрован, или я думаю об этом неправильно?
Так что я полностью переосмыслил это. Не уверен, что это обязательно лучшее решение, но оно намного быстрее. Причина, по которой запрос выполнялся так медленно, заключалась в фильтре по 2 первичным ключам. Запрос выполнялся для каждого ученика в классе, так что, возможно, 20-30 раз, что означало, что он занимал > 30 секунд.
Решение
Я свел все это в один запрос, выполняемый до цикла, и вытащил данные для всех пользователей-студентов в этот единственный запрос. Я преобразовал его в список значений.
queryset = SelfEvaluatedStatement.objects.filter(
evaluation_statement__sku__topic__subject=subject,
evaluation_statement__sku__level=level,
user__in=student_users
)
my_values = list(queryset.values_list('user__username', 'rating'))
Затем я использовал Python для итерации по списку значений, и это решение было значительно быстрее из-за всего 1 запроса к базе данных.