diff --git a/aleksis/apps/chronos/managers.py b/aleksis/apps/chronos/managers.py
index d52c750d5575910fa50299628ab6735ddb7d142b..07695bb22e7361f3cbfa02b8d5553d2ad6ed5b5d 100644
--- a/aleksis/apps/chronos/managers.py
+++ b/aleksis/apps/chronos/managers.py
@@ -25,63 +25,154 @@ class TimetableType(Enum):
 class LessonEventQuerySet(RecurrencePolymorphicQuerySet):
     """Queryset with special query methods for lesson events."""
 
+    @staticmethod
+    def for_teacher_q(teacher: Union[int, Person]) -> Q:
+        """Get all lesson events for a certain person as teacher (including amends)."""
+        from .models import LessonEvent
+
+        amended = (
+            LessonEvent.objects.filter(amended_by__isnull=False, teachers=teacher)
+            .values_list("amended_by__pk", flat=True)
+            .union(LessonEvent.objects.filter(teachers=teacher).values_list("pk", flat=True))
+        )
+        return Q(pk__in=amended)
+
     def for_teacher(self, teacher: Union[int, Person]) -> "LessonEventQuerySet":
         """Get all lesson events for a certain person as teacher (including amends)."""
+        return self.filter(self.for_teacher_q(teacher)).distinct()
+
+    @staticmethod
+    def for_participant_q(person: Union[int, Person]) -> Q:
+        """Get all lesson events the person participates in (including amends)."""
         from .models import LessonEvent
 
-        amended = LessonEvent.objects.filter(
-            amended_by__isnull=False, teachers=teacher
-        ).values_list("amended_by__pk", flat=True)
-        return self.filter(Q(teachers=teacher) | Q(pk__in=amended)).distinct()
+        amended = (
+            LessonEvent.objects.filter(amended_by__isnull=False, groups__members=person)
+            .values_list("amended_by__pk", flat=True)
+            .union(LessonEvent.objects.filter(groups__members=person).values_list("pk", flat=True))
+        )
+        return Q(pk__in=amended)
 
     def for_participant(self, person: Union[int, Person]) -> "LessonEventQuerySet":
         """Get all lesson events the person participates in (including amends)."""
+        return self.filter(self.for_participant_q(person)).distinct()
+
+    @staticmethod
+    def for_group_q(group: Union[int, Group]) -> Q:
+        """Get all lesson events for a certain group (including amends/as parent group)."""
         from .models import LessonEvent
 
-        amended = LessonEvent.objects.filter(
-            amended_by__isnull=False, groups__members=person
-        ).values_list("amended_by__pk", flat=True)
-        return self.filter(Q(groups__members=person) | Q(pk__in=amended)).distinct()
+        amended = (
+            LessonEvent.objects.filter(amended_by__isnull=False, groups=group)
+            .values_list("amended_by__pk", flat=True)
+            .union(
+                LessonEvent.objects.filter(
+                    amended_by__isnull=False, groups__parent_groups=group
+                ).values_list("amended_by__pk", flat=True)
+            )
+            .union(LessonEvent.objects.filter(groups=group).values_list("pk", flat=True))
+            .union(
+                LessonEvent.objects.filter(groups__parent_groups=group).values_list("pk", flat=True)
+            )
+        )
+        return Q(pk__in=amended)
 
     def for_group(self, group: Union[int, Group]) -> "LessonEventQuerySet":
         """Get all lesson events for a certain group (including amends/as parent group)."""
+        return self.filter(self.for_group_q(group)).distinct()
+
+    @staticmethod
+    def for_room_q(room: Union[int, Room]) -> Q:
+        """Get all lesson events for a certain room (including amends)."""
         from .models import LessonEvent
 
-        amended = LessonEvent.objects.filter(
-            Q(amended_by__isnull=False) & (Q(groups=group) | Q(groups__parent_groups=group))
-        ).values_list("amended_by__pk", flat=True)
-        return self.filter(
-            Q(groups=group) | Q(groups__parent_groups=group) | Q(pk__in=amended)
-        ).distinct()
+        amended = (
+            LessonEvent.objects.filter(amended_by__isnull=False, rooms=room)
+            .values_list("amended_by__pk", flat=True)
+            .union(LessonEvent.objects.filter(rooms=room).values_list("pk", flat=True))
+        )
+        return Q(pk__in=amended)
 
     def for_room(self, room: Union[int, Room]) -> "LessonEventQuerySet":
         """Get all lesson events for a certain room (including amends)."""
+        return self.filter(self.for_room_q(room)).distinct()
+
+    @staticmethod
+    def for_course_q(course: Union[int, Course]) -> Q:
+        """Get all lesson events for a certain course (including amends)."""
         from .models import LessonEvent
 
-        amended = LessonEvent.objects.filter(
-            Q(amended_by__isnull=False) & (Q(rooms=room))
-        ).values_list("amended_by__pk", flat=True)
-        return self.filter(Q(rooms=room) | Q(pk__in=amended)).distinct()
+        amended = (
+            LessonEvent.objects.filter(amended_by__isnull=False, course=course)
+            .values_list("amended_by__pk", flat=True)
+            .union(LessonEvent.objects.filter(course=course).values_list("pk", flat=True))
+        )
+        return Q(pk__in=amended)
 
     def for_course(self, course: Union[int, Course]) -> "LessonEventQuerySet":
         """Get all lesson events for a certain course (including amends)."""
+        return self.filter(self.for_course_q(course)).distinct()
+
+    @staticmethod
+    def for_person_q(person: Union[int, Person]) -> Q:
+        """Get all lesson events for a certain person (as teacher/participant, including amends)."""
         from .models import LessonEvent
 
-        amended = LessonEvent.objects.filter(amended_by__isnull=False, course=course).values_list(
-            "amended_by__pk", flat=True
+        amended = (
+            LessonEvent.objects.filter(amended_by__isnull=False, teachers=person)
+            .values_list("amended_by__pk", flat=True)
+            .union(
+                LessonEvent.objects.filter(
+                    amended_by__isnull=False, groups__members=person
+                ).values_list("amended_by__pk", flat=True)
+            )
+            .union(LessonEvent.objects.filter(teachers=person).values_list("pk", flat=True))
+            .union(LessonEvent.objects.filter(groups__members=person).values_list("pk", flat=True))
         )
-        return self.filter(Q(course=course) | Q(pk__in=amended)).distinct()
+        return Q(pk__in=amended)
 
     def for_person(self, person: Union[int, Person]) -> "LessonEventQuerySet":
         """Get all lesson events for a certain person (as teacher/participant, including amends)."""
+        return self.filter(self.for_person_q(person)).distinct()
+
+    @staticmethod
+    def related_to_person_q(person: Union[int, Person]) -> Q:
+        """Get all lesson events a certain person is allowed to see.
+
+        This includes all lesson events the person is assigned to as
+        teacher/participant/group owner/parent group owner,
+        including those amended.
+        """
         from .models import LessonEvent
 
-        amended = LessonEvent.objects.filter(
-            Q(amended_by__isnull=False) & (Q(teachers=person) | Q(groups__members=person))
-        ).values_list("amended_by__pk", flat=True)
-        return self.filter(
-            Q(teachers=person) | Q(groups__members=person) | Q(pk__in=amended)
-        ).distinct()
+        amended = (
+            LessonEvent.objects.filter(amended_by__isnull=False, teachers=person)
+            .values_list("amended_by__pk", flat=True)
+            .union(
+                LessonEvent.objects.filter(
+                    amended_by__isnull=False, groups__members=person
+                ).values_list("amended_by__pk", flat=True)
+            )
+            .union(
+                LessonEvent.objects.filter(
+                    amended_by__isnull=False, groups__owners=person
+                ).values_list("amended_by__pk", flat=True)
+            )
+            .union(
+                LessonEvent.objects.filter(
+                    amended_by__isnull=False, groups__parent_groups__owners=person
+                ).values_list("amended_by__pk", flat=True)
+            )
+            .union(LessonEvent.objects.filter(teachers=person).values_list("pk", flat=True))
+            .union(LessonEvent.objects.filter(groups__members=person).values_list("pk", flat=True))
+            .union(LessonEvent.objects.filter(groups__owners=person).values_list("pk", flat=True))
+            .union(
+                LessonEvent.objects.filter(groups__parent_groups__owners=person).values_list(
+                    "pk", flat=True
+                )
+            )
+        )
+        return Q(pk__in=amended)
 
     def related_to_person(self, person: Union[int, Person]) -> "LessonEventQuerySet":
         """Get all lesson events a certain person is allowed to see.
@@ -90,36 +181,34 @@ class LessonEventQuerySet(RecurrencePolymorphicQuerySet):
         teacher/participant/group owner/parent group owner,
         including those amended.
         """
-        from .models import LessonEvent
+        return self.filter(self.related_to_person_q(person)).distinct()
 
-        amended = LessonEvent.objects.filter(
-            Q(amended_by__isnull=False)
-            & (
-                Q(teachers=person)
-                | Q(groups__members=person)
-                | Q(groups__owners=person)
-                | Q(groups__parent_groups__owners=person)
-            )
-        ).values_list("amended_by__pk", flat=True)
-        return self.filter(
-            Q(teachers=person)
-            | Q(groups__members=person)
-            | Q(groups__owners=person)
-            | Q(groups__parent_groups__owners=person)
-            | Q(pk__in=amended)
-        ).distinct()
+    @staticmethod
+    def not_amended_q() -> Q:
+        """Get all lesson events that are not amended."""
+        return Q(amended_by__isnull=True)
 
     def not_amended(self) -> "LessonEventQuerySet":
         """Get all lesson events that are not amended."""
-        return self.filter(amended_by__isnull=True)
+        return self.filter(self.not_amended_q())
+
+    @staticmethod
+    def not_amending_q() -> Q:
+        """Get all lesson events that are not amending other events."""
+        return Q(amends__isnull=True)
 
     def not_amending(self) -> "LessonEventQuerySet":
         """Get all lesson events that are not amending other events."""
-        return self.filter(amends__isnull=True)
+        return self.filter(self.not_amending_q())
+
+    @staticmethod
+    def amending_q() -> Q:
+        """Get all lesson events that are amending other events."""
+        return Q(amends__isnull=False)
 
     def amending(self) -> "LessonEventQuerySet":
         """Get all lesson events that are amending other events."""
-        return self.filter(amends__isnull=False)
+        return self.filter(self.amending_q())
 
 
 class SupervisionEventQuerySet(LessonEventQuerySet):
diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py
index d2ca3cdd4c77e26f716c3a51af883fe1eb16cc75..8f3a04d809c6eca20bba019516c0f9a22cafe9cb 100644
--- a/aleksis/apps/chronos/models.py
+++ b/aleksis/apps/chronos/models.py
@@ -7,10 +7,9 @@ from datetime import date
 from typing import Any
 
 from django.contrib.contenttypes.models import ContentType
-from django.core.exceptions import PermissionDenied
 from django.core.validators import MinValueValidator
 from django.db import models
-from django.db.models import QuerySet
+from django.db.models import Q, QuerySet
 from django.dispatch import receiver
 from django.http import HttpRequest
 from django.template.loader import render_to_string
@@ -407,23 +406,22 @@ class LessonEvent(CalendarEvent):
         params: dict[str, any] | None = None,
         no_effect: bool = False,
         **kwargs,
-    ) -> Iterable:
+    ) -> QuerySet:
         """Return all objects that should be included in the calendar."""
         if no_effect:
             return super().get_objects(request, params, **kwargs)
-        objs = (
-            super()
-            .get_objects(request, params, **kwargs)
-            .not_instance_of(SupervisionEvent)
-            .select_related("subject", "course")
-            .prefetch_related("groups", "teachers", "rooms", "groups__members")
-        )
 
         if request and not has_person(request.user):
-            raise PermissionDenied()
+            return cls.objects.none()
+
+        q = Q()
 
         if params:
-            obj_id = int(params.get("id", 0))
+            try:
+                obj_id = int(params.get("id", 0))
+            except ValueError:
+                obj_id = None
+
             type_ = params.get("type", None)
             not_amended = params.get("not_amended", False)
             not_amending = params.get("not_amending", False)
@@ -431,36 +429,44 @@ class LessonEvent(CalendarEvent):
             own = params.get("own", False)
 
             if not_amended:
-                objs = objs.not_amended()
+                q = q & LessonEventQuerySet.not_amended_q()
 
             if not_amending:
-                objs = objs.not_amending()
+                q = q & LessonEventQuerySet.not_amending_q()
 
             if amending:
-                objs = objs.amending()
+                q = q & LessonEventQuerySet.amending_q()
 
             if request and "own" in params:
                 if own:
-                    objs = objs.for_person(request.user.person)
+                    q = q & LessonEventQuerySet.for_person_q(request.user.person)
                 else:
-                    objs = objs.related_to_person(request.user.person)
+                    q = q & LessonEventQuerySet.related_to_person_q(request.user.person)
 
             if type_ and obj_id:
                 if type_ == "TEACHER":
-                    return objs.for_teacher(obj_id)
+                    q = q & LessonEventQuerySet.for_teacher_q(obj_id)
                 elif type_ == "PARTICIPANT":
-                    return objs.for_participant(obj_id)
+                    q = q & LessonEventQuerySet.for_participant_q(obj_id)
                 elif type_ == "GROUP":
-                    return objs.for_group(obj_id)
+                    q = q & LessonEventQuerySet.for_group_q(obj_id)
                 elif type_ == "ROOM":
-                    return objs.for_room(obj_id)
+                    q = q & LessonEventQuerySet.for_room_q(obj_id)
                 elif type_ == "COURSE":
-                    return objs.for_course(obj_id)
-
-            if "own" in params:
-                return objs
-        if request:
-            return objs.for_person(request.user.person)
+                    q = q & LessonEventQuerySet.for_course_q(obj_id)
+
+        elif request:
+            q = q & LessonEventQuerySet.for_person_q(request.user.person)
+
+        objs = super().get_objects(
+            request,
+            params,
+            start_qs=cls.objects.not_instance_of(SupervisionEvent),
+            additional_filter=q,
+            select_related=["subject", "course"],
+            prefetch_related=["groups", "teachers", "rooms", "groups__members"],
+            **kwargs,
+        )
         return objs
 
     class Meta: