Optimize exam collection queries by annotating exam counts and prefetching authors to improve template performance

This commit is contained in:
Ross
2025-11-07 22:16:24 +00:00
parent 00a675b715
commit b424defd57
2 changed files with 29 additions and 7 deletions
@@ -27,12 +27,10 @@
<span class="badge bg-secondary" title="Archived">Archived</span>
{% endif %}
{# Total exams count (sum of known related exam sets) #}
{% with a=collection.anatomy_exams.count l=collection.longs_exams.count p=collection.physics_exams.count r=collection.rapids_exams.count s=collection.sbas_exams.count %}
{% with total=a|add:l|add:p|add:r|add:s %}
<span class="badge bg-info text-dark ms-1" title="Total exams">{{ total }} exams</span>
{% endwith %}
{# Per-type badges (only show non-zero) #}
{# Use annotated counts provided by the view to avoid per-card COUNT queries #}
<span class="badge bg-info text-dark ms-1" title="Total exams">{{ collection.total_count }} exams</span>
{# Per-type badges (only show non-zero) #}
{% with a=collection.anatomy_count l=collection.longs_count p=collection.physics_count r=collection.rapids_count s=collection.sbas_count %}
{% if a %}<span class="badge bg-primary ms-1">Anatomy {{ a }}</span>{% endif %}
{% if l %}<span class="badge bg-primary ms-1">Longs {{ l }}</span>{% endif %}
{% if p %}<span class="badge bg-primary ms-1">Physics {{ p }}</span>{% endif %}
+25 -1
View File
@@ -67,7 +67,7 @@ from generic.mixins import CheckCanEditMixin, SuperuserRequiredMixin
import zipfile
from django.core.files.base import ContentFile
from django.db.models import Q
from django.db.models import Q, Count, F
from .forms import (
CidGroupExamForm,
@@ -4777,6 +4777,30 @@ class SupervisorList(CidManagerRequiredMixin, SingleTableMixin, FilterView):
class ExamCollectionList(ListView):
model = ExamCollection
def get_queryset(self):
"""Annotate exam counts per collection and prefetch authors to avoid N+1 queries in templates."""
qs = (
ExamCollection.objects.all()
.annotate(
anatomy_count=Count("anatomy_exams", filter=Q(anatomy_exams__archive=False)),
longs_count=Count("longs_exams", filter=Q(longs_exams__archive=False)),
physics_count=Count("physics_exams", filter=Q(physics_exams__archive=False)),
rapids_count=Count("rapids_exams", filter=Q(rapids_exams__archive=False)),
sbas_count=Count("sbas_exams", filter=Q(sbas_exams__archive=False)),
)
.annotate(
total_count=F("anatomy_count")
+F("longs_count")
+F("physics_count")
+F("rapids_count")
+F("sbas_count")
)
.prefetch_related("author")
.order_by("name")
)
return qs
class ExamCollectionDetail(DetailView, AuthorRequiredMixin):