django 过滤一个 prefetch_related 查询集
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 个主键。 class 中每个学生的查询都是 运行,所以可能是 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 个数据库查询,这个解决方案明显更快。
我正在尝试将 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 个主键。 class 中每个学生的查询都是 运行,所以可能是 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 个数据库查询,这个解决方案明显更快。