From f99e45184351338ca2be751517f0bbaa9daeee23 Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Fri, 22 Nov 2024 16:03:34 +0100
Subject: [PATCH] Prefetch personal notes to avoid additional queries

---
 aleksis/apps/alsijil/models.py                      |  4 +++-
 aleksis/apps/alsijil/schema/documentation.py        |  5 +++++
 aleksis/apps/alsijil/schema/participation_status.py | 12 ++++++++++++
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py
index d681e04ad..4d2487e0c 100644
--- a/aleksis/apps/alsijil/models.py
+++ b/aleksis/apps/alsijil/models.py
@@ -154,7 +154,9 @@ class Documentation(CalendarEvent):
                 datetime_end__gte=datetime_start,
                 amends__in=[e["REFERENCE_OBJECT"] for e in events],
             )
-            .prefetch_related("participations", "teachers")
+            .prefetch_related(
+                "participations", "teachers", "personal_notes", "personal_notes__extra_mark"
+            )
             .select_related("course", "subject")
         )
 
diff --git a/aleksis/apps/alsijil/schema/documentation.py b/aleksis/apps/alsijil/schema/documentation.py
index fe45b7fb2..93e844c56 100644
--- a/aleksis/apps/alsijil/schema/documentation.py
+++ b/aleksis/apps/alsijil/schema/documentation.py
@@ -117,6 +117,11 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp
                     p for p in root.participations.all() if p.person == info.context.user.person
                 ]
             return []
+
+        # Annotate participations with prefetched documentation data for personal notes
+        for participation in root.participations.all():
+            participation._prefetched_documentation = root
+
         return root.participations.all()
 
 
diff --git a/aleksis/apps/alsijil/schema/participation_status.py b/aleksis/apps/alsijil/schema/participation_status.py
index 22e582059..bb0e24e05 100644
--- a/aleksis/apps/alsijil/schema/participation_status.py
+++ b/aleksis/apps/alsijil/schema/participation_status.py
@@ -41,6 +41,12 @@ class ParticipationStatusType(
 
     @staticmethod
     def resolve_notes_with_extra_mark(root: ParticipationStatus, info, **kwargs):
+        if hasattr(root, "_prefetched_documentation"):
+            return [
+                p
+                for p in root._prefetched_documentation.personal_notes.all()
+                if p.person_id == root.person_id and p.extra_mark
+            ]
         return NewPersonalNote.objects.filter(
             person=root.person,
             documentation=root.related_documentation,
@@ -49,6 +55,12 @@ class ParticipationStatusType(
 
     @staticmethod
     def resolve_notes_with_note(root: ParticipationStatus, info, **kwargs):
+        if hasattr(root, "_prefetched_documentation"):
+            return [
+                p
+                for p in root._prefetched_documentation.personal_notes.all()
+                if p.person_id == root.person_id and p.note
+            ]
         return NewPersonalNote.objects.filter(
             person=root.person,
             documentation=root.related_documentation,
-- 
GitLab