Optimize exam list retrieval by consolidating queries and annotating candidate counts for improved performance
This commit is contained in:
+18
-14
@@ -1902,27 +1902,31 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
|
|
||||||
@method_decorator(login_required)
|
@method_decorator(login_required)
|
||||||
def exam_list(self, request, all=False, collection=None):
|
def exam_list(self, request, all=False, collection=None):
|
||||||
|
# Build a single queryset and annotate candidate counts to avoid per-item queries
|
||||||
if collection is None:
|
if collection is None:
|
||||||
if not self.check_user_access(request.user):
|
if not self.check_user_access(request.user):
|
||||||
# raise PermissionDenied
|
# Use a single queryset with Q to include authored or marked exams
|
||||||
exam_list = self.Exam.objects.filter(
|
|
||||||
author__id=request.user.id, exam_mode=True
|
|
||||||
).order_by("name")
|
|
||||||
|
|
||||||
|
|
||||||
exam_list = exam_list | self.Exam.objects.filter(
|
|
||||||
markers__id=request.user.id, exam_mode=True
|
|
||||||
).order_by("name")
|
|
||||||
else:
|
|
||||||
exam_list = (
|
exam_list = (
|
||||||
self.Exam.objects.prefetch_related(
|
self.Exam.objects.filter(
|
||||||
"valid_user_users", "valid_cid_users"
|
(Q(author__id=request.user.id) | Q(markers__id=request.user.id)),
|
||||||
|
exam_mode=True,
|
||||||
)
|
)
|
||||||
.filter(exam_mode=True)
|
.distinct()
|
||||||
.order_by("name")
|
.order_by("name")
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
exam_list = self.Exam.objects.filter(exam_mode=True, examcollection__in=[collection]).order_by("name")
|
exam_list = self.Exam.objects.filter(exam_mode=True).order_by("name")
|
||||||
|
else:
|
||||||
|
exam_list = (
|
||||||
|
self.Exam.objects.filter(exam_mode=True, examcollection__in=[collection])
|
||||||
|
.order_by("name")
|
||||||
|
)
|
||||||
|
|
||||||
|
# Annotate counts for template usage so `.count()` is not called per-object
|
||||||
|
exam_list = exam_list.annotate(
|
||||||
|
valid_cid_users_count=Count("valid_cid_users", filter=Q(valid_cid_users__active=True)),
|
||||||
|
valid_user_users_count=Count("valid_user_users", filter=Q(valid_user_users__is_active=True)),
|
||||||
|
).select_related("examcollection").prefetch_related("author")
|
||||||
|
|
||||||
if not all:
|
if not all:
|
||||||
exam_list = exam_list.filter(archive=False).order_by("name")
|
exam_list = exam_list.filter(archive=False).order_by("name")
|
||||||
|
|||||||
Reference in New Issue
Block a user