From 44ace3bc2e9d815b344ef4fcb115d1452b1033dc Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Mon, 15 Aug 2022 13:46:11 +0200
Subject: [PATCH] Add distinct to combined queries with persons

---
 CHANGELOG.rst                 |  5 +++++
 aleksis/apps/alsijil/views.py | 40 ++++++++++++++++++++++-------------
 2 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 9946633ec..a79287ec7 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -9,6 +9,11 @@ and this project adheres to `Semantic Versioning`_.
 Unreleased
 ----------
 
+Fixed
+~~~~~
+
+* Students were displayed multiple times in class register views.
+
 `2.1`_ - 2022-06-25
 -------------------
 
diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py
index c1ef90f69..538b24e7d 100644
--- a/aleksis/apps/alsijil/views.py
+++ b/aleksis/apps/alsijil/views.py
@@ -240,8 +240,10 @@ def register_object(
         else:
             persons = Person.objects.all()
 
-        persons_qs = register_object.get_personal_notes(persons, wanted_week).filter(
-            person__member_of__in=request.user.person.owner_of.all()
+        persons_qs = (
+            register_object.get_personal_notes(persons, wanted_week)
+            .filter(person__member_of__in=request.user.person.owner_of.all())
+            .distinct()
         )
 
         # Annotate group roles
@@ -476,12 +478,16 @@ def week_view(
         if not request.user.has_perm("alsijil.view_week_personalnote_rule", instance):
             persons_qs = persons_qs.filter(pk=request.user.person.pk)
         elif group:
-            persons_qs = persons_qs.filter(member_of=group).filter(
-                member_of__in=request.user.person.owner_of.all()
+            persons_qs = (
+                persons_qs.filter(member_of=group)
+                .filter(member_of__in=request.user.person.owner_of.all())
+                .distinct()
             )
         else:
-            persons_qs = persons_qs.filter(member_of__in=groups).filter(
-                member_of__in=request.user.person.owner_of.all()
+            persons_qs = (
+                persons_qs.filter(member_of__in=groups)
+                .filter(member_of__in=request.user.person.owner_of.all())
+                .distinct()
             )
 
         # Prefetch object permissions for persons and groups the persons are members of
@@ -792,12 +798,16 @@ def my_students(request: HttpRequest) -> HttpResponse:
 
     new_groups = []
     for group in relevant_groups:
-        persons = group.generate_person_list_with_class_register_statistics(
-            group.members.prefetch_related(
-                "primary_group__owners",
-                Prefetch("member_of", queryset=relevant_groups, to_attr="member_of_prefetched"),
+        persons = (
+            group.generate_person_list_with_class_register_statistics(
+                group.members.prefetch_related(
+                    "primary_group__owners",
+                    Prefetch("member_of", queryset=relevant_groups, to_attr="member_of_prefetched"),
+                )
             )
-        ).filter(member_of__in=request.user.person.owner_of.all())
+            .filter(member_of__in=request.user.person.owner_of.all())
+            .distinct()
+        )
         persons_for_group = []
         for person in persons:
             person.set_object_permission_checker(checker)
@@ -830,10 +840,10 @@ class StudentsList(PermissionRequiredMixin, DetailView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context["group"] = self.object
-        context[
-            "persons"
-        ] = self.object.generate_person_list_with_class_register_statistics().filter(
-            member_of__in=self.request.user.person.owner_of.all()
+        context["persons"] = (
+            self.object.generate_person_list_with_class_register_statistics()
+            .filter(member_of__in=self.request.user.person.owner_of.all())
+            .distinct()
         )
         context["extra_marks"] = ExtraMark.objects.all()
         context["excuse_types"] = ExcuseType.objects.filter(count_as_absent=True)
-- 
GitLab