From d72df7c120680cc669a4e7ce76474ccdca3ab1c1 Mon Sep 17 00:00:00 2001
From: Konrad Mohrfeldt <konrad.mohrfeldt@farbdev.org>
Date: Thu, 7 Sep 2023 20:05:17 +0200
Subject: [PATCH] fix: restore filter backends

In aa7e7f41295dec4eb2db49ae0376749a83b369bd filters were renamed
to a camelCase scheme. This is actually wrong, because the filter
names are already transformed to snake_case when the are applied
to the FilterSet.
---
 program/filters.py | 106 ++++++++++++++++++++++-----------------------
 program/views.py   |  82 +----------------------------------
 2 files changed, 53 insertions(+), 135 deletions(-)

diff --git a/program/filters.py b/program/filters.py
index 823ed52e..88e64999 100644
--- a/program/filters.py
+++ b/program/filters.py
@@ -39,17 +39,19 @@ class IntegerInFilter(filters.BaseInFilter):
 
 
 class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
-    categoryIds = IntegerInFilter(
+    category_ids = IntegerInFilter(
+        field_name="category",
         help_text="Return only shows of the given category or categories.",
     )
-    categorySlug = filters.CharFilter(
-        field_name="category", help_text="Return only shows of the given category slug."
+    category_slug = filters.CharFilter(
+        field_name="category__slug",
+        help_text="Return only shows of the given category slug.",
     )
-    hostIds = IntegerInFilter(
+    host_ids = IntegerInFilter(
         field_name="hosts",
         help_text="Return only shows assigned to the given host(s).",
     )
-    isActive = filters.BooleanFilter(
+    is_active = filters.BooleanFilter(
         field_name="is_active",
         method="filter_active",
         help_text=(
@@ -57,35 +59,41 @@ class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
             "or past or upcoming shows if false."
         ),
     )
-    isPublic = filters.BooleanFilter(
+    is_public = filters.BooleanFilter(
         field_name="is_public",
         help_text="Return only shows that are public/non-public.",
     )
-    languageIds = IntegerInFilter(
+    language_ids = IntegerInFilter(
+        field_name="language",
         help_text="Return only shows of the given language(s).",
     )
-    musicFocusIds = IntegerInFilter(
+    music_focus_ids = IntegerInFilter(
         field_name="music_focus",
         help_text="Return only shows with given music focus(es).",
     )
-    musicFocusSlug = filters.CharFilter(
-        field_name="music_focus", help_text="Return only shows with the give music focus slug."
+    music_focus_slug = filters.CharFilter(
+        field_name="music_focus__slug",
+        help_text="Return only shows with the give music focus slug.",
     )
-    ownerIds = IntegerInFilter(
+    owner_ids = IntegerInFilter(
         field_name="owners",
         help_text="Return only shows that belong to the given owner(s).",
     )
-    topicIds = IntegerInFilter(
+    topic_ids = IntegerInFilter(
+        field_name="topic",
         help_text="Return only shows of the given topic(s).",
     )
-    topicSlug = filters.CharFilter(
-        field_name="topic", help_text="Return only shows of the given topic slug."
+    topic_slug = filters.CharFilter(
+        field_name="topic__slug",
+        help_text="Return only shows of the given topic slug.",
     )
-    typeId = IntegerInFilter(
+    type_id = IntegerInFilter(
+        field_name="type",
         help_text="Return only shows of a given type.",
     )
-    typeSlug = filters.CharFilter(
-        field_name="type", help_text="Return only shows of the given type slug."
+    type_slug = filters.CharFilter(
+        field_name="type__slug",
+        help_text="Return only shows of the given type slug.",
     )
 
     def filter_active(self, queryset: QuerySet, name: str, value: bool):
@@ -116,31 +124,22 @@ class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
         else:
             return queryset.exclude(id__in=show_ids, is_active=True)
 
-    @property
-    def qs(self):
-        # allow pagination query parameters in the GET request
-        fields = self.Meta.fields + ["limit", "offset"]
-        if any([key for key in self.request.GET.keys() if key not in fields]):
-            return None
-        else:
-            return super().qs
-
     class Meta:
         model = models.Show
         fields = [
-            "categoryIds",
-            "categorySlug",
-            "hostIds",
-            "isActive",
-            "isPublic",
-            "languageIds",
-            "musicFocusIds",
-            "musicFocusSlug",
-            "ownerIds",
-            "topicIds",
-            "topicSlug",
-            "typeId",
-            "typeSlug",
+            "category_ids",
+            "category_slug",
+            "host_ids",
+            "is_active",
+            "is_public",
+            "language_ids",
+            "music_focus_ids",
+            "music_focus_slug",
+            "owner_ids",
+            "topic_ids",
+            "topic_slug",
+            "type_id",
+            "type_slug",
         ]
 
 
@@ -174,12 +173,12 @@ class TimeSlotFilterSet(filters.FilterSet):
         ),
     )
 
-    scheduleIds = IntegerInFilter(
+    schedule_ids = IntegerInFilter(
         field_name="schedule",
         help_text="Return only timeslots that belong to the specified schedule(s).",
     )
 
-    showIds = IntegerInFilter(
+    show_ids = IntegerInFilter(
         field_name="schedule__show",
         help_text="Return only timeslots that belong to the specified show(s).",
     )
@@ -241,6 +240,8 @@ class TimeSlotFilterSet(filters.FilterSet):
             "start",
             "end",
             "surrounding",
+            "schedule_ids",
+            "show_ids",
         ]
 
 
@@ -249,41 +250,38 @@ class NoteFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
         field_name="id",
         help_text="Return only notes matching the specified id(s).",
     )
-    ownerIds = IntegerInFilter(
+    owner_ids = IntegerInFilter(
         field_name="owner",
         help_text="Return only notes that belong to the specified owner(s).",
     )
-    showIds = IntegerInFilter(
+    show_ids = IntegerInFilter(
         field_name="timeslot__show",
         help_text="Return only notes that belong to the specified show(s).",
     )
-    showOwnerIds = IntegerInFilter(
+    show_owner_ids = IntegerInFilter(
         field_name="timeslot__show__owners",
         help_text="Return only notes by show the specified owner(s): all notes the user may edit.",
     )
-    timeslotIds = IntegerInFilter(
+    timeslot_ids = IntegerInFilter(
         field_name="timeslot",
         help_text="Return only notes that belong to the specified timeslot(s).",
     )
 
     class Meta:
         model = models.Note
-        help_texts = {
-            "ownerId": "Return only notes created by the specified user.",
-        }
         fields = [
             "ids",
-            "ownerIds",
-            "showIds",
-            "showOwnerIds",
-            "timeslotIds",
+            "owner_ids",
+            "show_ids",
+            "show_owner_ids",
+            "timeslot_ids",
         ]
 
 
 class ActiveFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
-    isActive = filters.BooleanFilter(field_name="is_active")
+    is_active = filters.BooleanFilter(field_name="is_active")
 
     class Meta:
         fields = [
-            "isActive",
+            "is_active",
         ]
diff --git a/program/views.py b/program/views.py
index ecdabf3e..41751b62 100644
--- a/program/views.py
+++ b/program/views.py
@@ -32,9 +32,8 @@ from rest_framework.pagination import LimitOffsetPagination
 from rest_framework.response import Response
 
 from django.contrib.auth.models import User
-from django.core.exceptions import FieldError
 from django.http import Http404, HttpResponse
-from django.shortcuts import get_list_or_404, get_object_or_404
+from django.shortcuts import get_object_or_404
 from django.utils import timezone
 from django.utils.translation import gettext as _
 from program import filters
@@ -376,42 +375,6 @@ class APIShowViewSet(DisabledObjectPermissionCheckMixin, viewsets.ModelViewSet):
     pagination_class = LimitOffsetPagination
     filterset_class = filters.ShowFilterSet
 
-    def list(self, request, *args, **kwargs):
-        filter_kwargs = {}
-
-        for key, value in request.query_params.items():
-            #  map query parameters to filter names
-            if value == "":
-                pass
-            elif key == "host_ids" or key == "owner_ids":
-                if value.count(",") > 0:
-                    filter_kwargs[f"{key[:-4]}s__id__in"] = value.split(",")
-                else:
-                    filter_kwargs[f"{key[:-4]}s__id"] = value
-            elif key.endswith("_ids"):
-                if value.count(",") > 0:
-                    filter_kwargs[f"{key[:-4]}__id__in"] = value.split(",")
-                else:
-                    filter_kwargs[f"{key[:-4]}__id"] = value
-            elif key.endswith("_id"):
-                filter_kwargs[f"{key[:-3]}__id"] = value
-            elif key.endswith("_slug"):
-                filter_kwargs[f"{key[:-5]}__slug"] = value
-            else:
-                filter_kwargs[key] = value
-
-        try:
-            queryset = get_list_or_404(self.get_queryset(), **filter_kwargs)
-        except FieldError:
-            queryset = None
-
-        if page := self.paginate_queryset(queryset) is not None:
-            serializer = self.get_serializer(page, many=True)
-            return self.get_paginated_response(serializer.data)
-
-        serializer = self.get_serializer(queryset, many=True)
-        return Response(serializer.data)
-
     def get_object(self):
         queryset = self.filter_queryset(self.get_queryset())
         lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
@@ -808,49 +771,6 @@ class APINoteViewSet(
     pagination_class = LimitOffsetPagination
     filterset_class = filters.NoteFilterSet
 
-    def list(self, request, *args, **kwargs):
-        filter_kwargs = {}
-
-        #  map query parameters to filter names
-        for key, value in request.query_params.items():
-            if value == "":
-                pass
-            elif key == "ids":
-                if value.count(",") > 0:
-                    filter_kwargs["id__in"] = value.split(",")
-                else:
-                    filter_kwargs["id"] = value
-            elif key == "show_ids":
-                if value.count(",") > 0:
-                    filter_kwargs["timeslot__show__in"] = value.split(",")
-                else:
-                    filter_kwargs["timeslot__show"] = value
-            elif key == "show_owner_ids":
-                if value.count(",") > 0:
-                    filter_kwargs["timeslot__show__owners__in"] = value.split(",")
-                else:
-                    filter_kwargs["timeslot__show__owners"] = value
-            elif key.endswith("_ids"):
-                if value.count(",") > 0:
-                    filter_kwargs[f"{key[:-4]}__in"] = value.split(",")
-                else:
-                    filter_kwargs[f"{key[:-4]}"] = value
-            else:
-                filter_kwargs[key] = value
-
-        try:
-            queryset = get_list_or_404(self.get_queryset(), **filter_kwargs)
-        except FieldError:
-            queryset = None
-
-        if page := self.paginate_queryset(queryset) is not None:
-            serializer = self.get_serializer(page, many=True)
-            return self.get_paginated_response(serializer.data)
-
-        serializer = self.get_serializer(queryset, many=True)
-
-        return Response(serializer.data)
-
     def get_serializer_context(self):
         # the serializer needs the request in the context
         context = super().get_serializer_context()
-- 
GitLab