Optimize collection_viva by aggressively prefetching and annotating related objects to prevent N+1 queries

This commit is contained in:
Ross
2026-02-09 12:15:36 +00:00
parent ab130a08ed
commit 23f33ac7ae
2 changed files with 32 additions and 22 deletions
+18 -17
View File
@@ -3111,31 +3111,32 @@ def collection_viva(request, pk):
# )
#)
# Prefetch and annotate aggressively to avoid N+1 queries in the viva view.
# - Prefetch `case__series` using the ordering from SeriesDetail
# - Prefetch only non-removed images for those series (ordered by position)
# - Prefetch case resources and display sets
from django.db.models import Prefetch as _Prefetch
series_images_qs = SeriesImage.objects.filter(removed=False).order_by("position")
series_qs = Series.objects.order_by("seriesdetail__sort_order").prefetch_related(
_Prefetch("images", queryset=series_images_qs)
)
casedetails = (
CaseDetail.objects
.filter(collection=collection)
.select_related("case")
.order_by("sort_order")
.prefetch_related(
# Prefetch series and their images directly on the case
"case__series",
"case__series__modality",
"case__series__examination",
"case__series__plane",
"case__series__contrast",
"case__series__images",
_Prefetch("case__series", queryset=series_qs),
_Prefetch("case__series__modality"),
_Prefetch("case__series__examination"),
_Prefetch("case__series__plane"),
_Prefetch("case__series__contrast"),
_Prefetch("case__caseresource_set"),
_Prefetch("case__display_sets"),
)
)
# Also annotate and prefetch additional related objects used by the viva
# template to avoid N+1 queries when rendering many cases.
casedetails = (
casedetails
.annotate(series_count=Count("case__seriesdetail"))
.prefetch_related(
"case__caseresource_set",
"case__display_sets",
)
)