From 3c38698ae9ee03909f6250f5a634ed2fd7f0a2ad Mon Sep 17 00:00:00 2001
From: Konrad Mohrfeldt <konrad.mohrfeldt@farbdev.org>
Date: Tue, 22 Mar 2022 15:47:41 +0100
Subject: [PATCH] =?UTF-8?q?fix:=20don=E2=80=99t=20restrict=20timeslot=20qu?=
 =?UTF-8?q?eryset=20on=20detail=20views?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The filter defaults caused the queryset to always yield results filtered
for the coming 60 days. We should only apply filter defaults when
listing timeslots, not when querying individual items.
---
 program/filters.py | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/program/filters.py b/program/filters.py
index e05e58d7..4afad051 100644
--- a/program/filters.py
+++ b/program/filters.py
@@ -3,7 +3,6 @@ import datetime
 from django_filters import rest_framework as filters
 from django_filters import widgets
 
-from django import forms
 from django.contrib.auth.models import User
 from django.db.models import Q, QuerySet
 from django.utils import timezone
@@ -182,16 +181,10 @@ class TimeSlotFilterSet(filters.FilterSet):
             queryset = self.filter_surrounding(queryset, "surrounding", timezone.now())
         return queryset
 
-    class Meta:
-        model = models.TimeSlot
-        fields = [
-            "order",
-            "start",
-            "end",
-            "surrounding",
-        ]
+    def get_form_class(self):
+        form_cls = super().get_form_class()
 
-        class form(forms.Form):
+        class TimeSlotFilterSetFormWithDefaults(form_cls):
             def clean_start(self):
                 start = self.cleaned_data.get("start", None)
                 return start or timezone.now().date()
@@ -200,6 +193,23 @@ class TimeSlotFilterSet(filters.FilterSet):
                 end = self.cleaned_data.get("end", None)
                 return end or self.cleaned_data["start"] + datetime.timedelta(days=60)
 
+        # We only want defaults to apply in the context of the list action.
+        # When accessing individual timeslots we don’t want the queryset to be restricted
+        # to the default range of 60 days as get_object would yield a 404 otherwise.
+        if self.request.parser_context["view"].action == "list":
+            return TimeSlotFilterSetFormWithDefaults
+        else:
+            return form_cls
+
+    class Meta:
+        model = models.TimeSlot
+        fields = [
+            "order",
+            "start",
+            "end",
+            "surrounding",
+        ]
+
 
 class NoteFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
     ids = ModelMultipleChoiceFilter(
-- 
GitLab