From 179565983e7cabdedde39bffddb076be400a368d Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Wed, 20 Jan 2021 15:34:37 +0100
Subject: [PATCH] [Full register] Remove some superfluous prefetch operations
 and organise the rest of the prefetching more efficient

---
 .../alsijil/print/full_register.html          | 62 +++++++++--------
 aleksis/apps/alsijil/views.py                 | 66 +++++++++++--------
 2 files changed, 67 insertions(+), 61 deletions(-)

diff --git a/aleksis/apps/alsijil/templates/alsijil/print/full_register.html b/aleksis/apps/alsijil/templates/alsijil/print/full_register.html
index 85ac0fbca..c95a168f7 100644
--- a/aleksis/apps/alsijil/templates/alsijil/print/full_register.html
+++ b/aleksis/apps/alsijil/templates/alsijil/print/full_register.html
@@ -316,40 +316,38 @@
       </thead>
 
       <tbody>
-      {% for note in person.personal_notes.all %}
-        {% if note.lesson_period in lesson_periods %}
-          {% if note.absent or note.late or note.remarks or note.extra_marks.all %}
-              {% weekday_to_date note.calendar_week note.lesson_period.period.weekday as note_date %}
-            <tr>
-              <td>{{ note_date }}</td>
-              <td>{{ note.lesson_period.period.period }}</td>
-              <td>{{ note.lesson_period.get_subject.short_name }} </td>
-              <td>{{ note.lesson_period.get_teachers.first.short_name }}</td>
-              <td>
-                {% if note.absent %}
-                  {% trans 'Yes' %}
-                  {% if note.excused %}
-                    {% if note.excuse_type %}
-                      ({{ note.excuse_type.short_name }})
-                    {% else %}
-                      ({% trans 'e' %})
-                    {% endif %}
+      {% for note in person.filtered_notes %}
+        {% if note.absent or note.late or note.remarks or note.extra_marks.all %}
+            {% weekday_to_date note.calendar_week note.lesson_period.period.weekday as note_date %}
+          <tr>
+            <td>{{ note_date }}</td>
+            <td>{{ note.lesson_period.period.period }}</td>
+            <td>{{ note.lesson_period.get_subject.short_name }} </td>
+            <td>{{ note.lesson_period.get_teachers.first.short_name }}</td>
+            <td>
+              {% if note.absent %}
+                {% trans 'Yes' %}
+                {% if note.excused %}
+                  {% if note.excuse_type %}
+                    ({{ note.excuse_type.short_name }})
+                  {% else %}
+                    ({% trans 'e' %})
                   {% endif %}
                 {% endif %}
-              </td>
-              <td>
-                {% if note.late %}
-                  {{ note.late }}'
-                {% endif %}
-              </td>
-              <td>
-                {% for extra_mark in note.extra_marks.all %}
-                  {{ extra_mark.short_name }}{% if not forloop.last %},{% endif %}
-                {% endfor %}
-              </td>
-              <td>{{ note.remarks }}</td>
-            </tr>
-          {% endif %}
+              {% endif %}
+            </td>
+            <td>
+              {% if note.late %}
+                {{ note.late }}'
+              {% endif %}
+            </td>
+            <td>
+              {% for extra_mark in note.extra_marks.all %}
+                {{ extra_mark.short_name }}{% if not forloop.last %},{% endif %}
+              {% endfor %}
+            </td>
+            <td>{{ note.remarks }}</td>
+          </tr>
         {% endif %}
       {% endfor %}
       </tbody>
diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py
index c5616940d..d5bbf0614 100644
--- a/aleksis/apps/alsijil/views.py
+++ b/aleksis/apps/alsijil/views.py
@@ -402,20 +402,29 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse:
 
     group = get_object_or_404(Group, pk=id_)
 
-    # Get all lesson periods for the selected group
-    lesson_periods = (
-        LessonPeriod.objects.filter_group(group)
-        .distinct()
+    personal_notes = (
+        PersonalNote.objects.select_related("lesson_period")
         .prefetch_related(
-            "documentations",
-            "personal_notes",
-            "personal_notes__excuse_type",
-            "personal_notes__extra_marks",
-            "personal_notes__person",
-            "personal_notes__groups_of_person",
+            "lesson_period__substitutions", "lesson_period__lesson__teachers", "groups_of_person"
+        )
+        .filter(~Q(remarks="") | Q(absent=True) | ~Q(late=0) | Q(extra_marks__isnull=False))
+        .filter(
+            Q(lesson_period__lesson__groups=group)
+            | Q(lesson_period__lesson__groups__parent_groups=group)
+        )
+    )
+    documentations = (
+        LessonDocumentation.objects.select_related("lesson_period")
+        .filter(~Q(topic="") | ~Q(group_note="") | ~Q(homework=""))
+        .filter(
+            Q(lesson_period__lesson__groups=group)
+            | Q(lesson_period__lesson__groups__parent_groups=group)
         )
     )
 
+    # Get all lesson periods for the selected group
+    lesson_periods = LessonPeriod.objects.filter_group(group).distinct()
+
     weeks = CalendarWeek.weeks_within(group.school_term.date_start, group.school_term.date_end,)
 
     periods_by_day = {}
@@ -428,39 +437,38 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse:
                 <= day
                 <= lesson_period.lesson.validity.date_end
             ):
-                documentations = list(
+                filtered_documentations = list(
                     filter(
-                        lambda d: d.week == week.week and d.year == week.year,
-                        lesson_period.documentations.all(),
+                        lambda d: d.week == week.week
+                        and d.year == week.year
+                        and d.lesson_period == lesson_period,
+                        documentations,
                     )
                 )
-                notes = list(
+                filtered_personal_notes = list(
                     filter(
-                        lambda d: d.week == week.week and d.year == week.year,
-                        lesson_period.personal_notes.all(),
+                        lambda d: d.week == week.week
+                        and d.year == week.year
+                        and d.lesson_period == lesson_period,
+                        personal_notes,
                     )
                 )
                 substitution = lesson_period.get_substitution(week)
 
                 periods_by_day.setdefault(day, []).append(
-                    (lesson_period, documentations, notes, substitution)
+                    (lesson_period, filtered_documentations, filtered_personal_notes, substitution)
                 )
 
-    persons = Person.objects.prefetch_related(
-        "personal_notes",
-        "personal_notes__excuse_type",
-        "personal_notes__extra_marks",
-        "personal_notes__lesson_period__lesson__subject",
-        "personal_notes__lesson_period__substitutions",
-        "personal_notes__lesson_period__substitutions__subject",
-        "personal_notes__lesson_period__substitutions__teachers",
-        "personal_notes__lesson_period__lesson__teachers",
-        "personal_notes__lesson_period__period",
-    )
+    persons = Person.objects.prefetch_related(None).select_related(None)
     persons = group.generate_person_list_with_class_register_statistics(persons)
 
+    prefetched_persons = []
+    for person in persons:
+        person.filtered_notes = list(filter(lambda d: d.person == person, personal_notes))
+        prefetched_persons.append(person)
+
     context["school_term"] = group.school_term
-    context["persons"] = persons
+    context["persons"] = prefetched_persons
     context["excuse_types"] = ExcuseType.objects.all()
     context["extra_marks"] = ExtraMark.objects.all()
     context["group"] = group
-- 
GitLab