我正在学习DRF并尝试使用查询集。我正在尝试优化以尽可能高效地工作。 目标是获取针对“艺术”专业的在职学生的成绩列表。
基于database optimization技术, 我运行了一些不同的更新,当我查看通过控制台的“网络”选项卡返回的时间时,没有发现差异。但是,我确实做到了,当我在模型过滤上运行.explain()方法时,在Seq扫描中看到的日志更少。 我能做到这一点吗?
例如: Grades.objects.filter(student_id__in = list(student_list))。order_by()
我还能做些什么来改善下面可能遗失的代码? -除了添加任何外键或主键模型更改之外。
class GradeViewSet(viewsets.ModelViewSet):
serializer_class = GradesSerializer
def retrieve(self, request, *args, **kwargs):
active_students = Student.objects.filter(active=True)
student_list = active_students.filter(major='Art').values_list('student_id')
queryset = Grades.objects.filter(student_id__in=student_list)
serializers = GradesSerializer(queryset, many=True)
return Response(serializers.data)
我正在尝试在Django中创建的SQL查询。
select * from app_grades g
join app_students s on g.student_id = s.student_id
where s.active = true and s.major = 'Art'
答案 0 :(得分:2)
您的代码将执行两个单独的数据库查询,建议您尝试以下查询:
queryset = Grades.objects.filter(student__active=True, student__major='Art')
此代码将检索完全相同的记录,但仅使用适当的JOIN
子句执行一次查询。
您可能想看看this part of the documentation。
由于缺少禁止使用查找的模型关系,我建议您使用Exists subuery。在这种特定情况下,查询将如下所示:
queryset = Grades.objects.annotate(student_passes_filter=Exists(
Student.objects.filter(id=OuterRef('student_id'), active=True, major='Art')
)).filter(student_passes_filter=True)
您将需要导入Exists
和OuterRef
。请注意,这些功能可从Django 1.11开始使用。
答案 1 :(得分:1)
您可能应该重新组合这些行以减少查询数量:
<?xml version="1.0"?>
<courses>
<course><courseID>cs601</courseID><courseName>Web Application Development</courseName></course>
<course><courseId>cs602</courseId><courseName>Server-Side Application Development</courseName></course>
<course><courseId>cs701</courseId><courseName>Rich Internet Application Development</courseName></course>
</courses>
进入:
active_students = Student.objects.filter(active=True)
student_list = active_students.filter(major='Art').values_list('student_id')
然后转换为列表