From 768e1bf8c54b2eda93bcb80878d98248324f832e Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 29 Dec 2025 12:18:31 +0000 Subject: [PATCH] Enhance ExamCollectionDetail queryset to prefetch related exams and annotate candidate counts for improved performance in templates --- generic/views.py | 62 ++++++++++++++++++++++++++++++++++++++++ templates/exam_list.html | 21 ++++++++++++-- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/generic/views.py b/generic/views.py index 7ac114d6..6abc9745 100644 --- a/generic/views.py +++ b/generic/views.py @@ -5875,6 +5875,68 @@ class ExamCollectionList(LoginRequiredMixin, ListView): class ExamCollectionDetail(AuthorRequiredMixin, DetailView): model = ExamCollection + + def get_queryset(self): + # Prefetch related exam sets and annotate candidate counts to avoid per-exam DB hits in templates + qs = super().get_queryset() + try: + from anatomy.models import Exam as AnatomyExam + from longs.models import Exam as LongsExam + from rapids.models import Exam as RapidsExam + from shorts.models import Exam as ShortsExam + from physics.models import Exam as PhysicsExam + from sbas.models import Exam as SbasExam + + qs = qs.prefetch_related( + Prefetch( + 'anatomy_exams', + queryset=AnatomyExam.objects.annotate( + valid_cid_users_count=Count('valid_cid_users'), + valid_user_users_count=Count('valid_user_users'), + ).prefetch_related('author'), + ), + Prefetch( + 'longs_exams', + queryset=LongsExam.objects.annotate( + valid_cid_users_count=Count('valid_cid_users'), + valid_user_users_count=Count('valid_user_users'), + ).prefetch_related('author'), + ), + Prefetch( + 'rapids_exams', + queryset=RapidsExam.objects.annotate( + valid_cid_users_count=Count('valid_cid_users'), + valid_user_users_count=Count('valid_user_users'), + ).prefetch_related('author'), + ), + Prefetch( + 'shorts_exams', + queryset=ShortsExam.objects.annotate( + valid_cid_users_count=Count('valid_cid_users'), + valid_user_users_count=Count('valid_user_users'), + ).prefetch_related('author'), + ), + Prefetch( + 'physics_exams', + queryset=PhysicsExam.objects.annotate( + valid_cid_users_count=Count('valid_cid_users'), + valid_user_users_count=Count('valid_user_users'), + ).prefetch_related('author'), + ), + Prefetch( + 'sbas_exams', + queryset=SbasExam.objects.annotate( + valid_cid_users_count=Count('valid_cid_users'), + valid_user_users_count=Count('valid_user_users'), + ).prefetch_related('author'), + ), + 'author', + ) + except Exception: + # If any app is missing or import fails, fall back to default queryset + pass + + return qs class ExamCollectionEdit(AuthorRequiredMixin, UpdateView): diff --git a/templates/exam_list.html b/templates/exam_list.html index e9e111df..5721c07a 100644 --- a/templates/exam_list.html +++ b/templates/exam_list.html @@ -17,9 +17,24 @@ {% if app_name == 'anatomy' %}Mark2{% endif %} {% endif %} - Candidates [ - {{exam.valid_cid_users.count}} - / {{exam.valid_user_users.count}}] + Candidates + [ + + {% if exam.valid_cid_users_count is not None %} + {{ exam.valid_cid_users_count }} + {% else %} + {{ exam.valid_cid_users.count }} + {% endif %} + + / + + {% if exam.valid_user_users_count is not None %} + {{ exam.valid_user_users_count }} + {% else %} + {{ exam.valid_user_users.count }} + {% endif %} + ] + Scores