From aa7e7f41295dec4eb2db49ae0376749a83b369bd Mon Sep 17 00:00:00 2001
From: Ernesto Rico Schmidt <ernesto@helsinki.at>
Date: Wed, 7 Jun 2023 22:43:14 -0400
Subject: [PATCH] refactor: use camelCase for query parameters

To be honest I'm not sure this is the right way to do it.
---
 program/filters.py | 106 +++++++++++++++++++++++++--------------------
 program/views.py   |  59 ++++++++++++++++++++++++-
 2 files changed, 118 insertions(+), 47 deletions(-)

diff --git a/program/filters.py b/program/filters.py
index 298111c8..ca507c82 100644
--- a/program/filters.py
+++ b/program/filters.py
@@ -39,7 +39,17 @@ class IntegerInFilter(filters.BaseInFilter):
 
 
 class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
-    active = filters.BooleanFilter(
+    categoryIds = IntegerInFilter(
+        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."
+    )
+    hostIds = IntegerInFilter(
+        field_name="hosts",
+        help_text="Return only shows assigned to the given host(s).",
+    )
+    isActive = filters.BooleanFilter(
         field_name="is_active",
         method="filter_active",
         help_text=(
@@ -47,46 +57,36 @@ class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
             "or past or upcoming shows if false."
         ),
     )
-    host = IntegerInFilter(
-        field_name="hosts",
-        help_text="Return only shows assigned to the given host(s).",
+    isPublic = filters.BooleanFilter(
+        field_name="is_public",
+        help_text="Return only shows that are public/non-public.",
+    )
+    languageIds = IntegerInFilter(
+        help_text="Return only shows of the given language(s).",
     )
-    music_focus = IntegerInFilter(
+    musicFocusIds = IntegerInFilter(
         field_name="music_focus",
         help_text="Return only shows with given music focus(es).",
     )
-    music_focus__slug = filters.CharFilter(
+    musicFocusSlug = filters.CharFilter(
         field_name="music_focus", help_text="Return only shows with the give music focus slug."
     )
-    owner = IntegerInFilter(
+    ownerIds = IntegerInFilter(
         field_name="owners",
         help_text="Return only shows that belong to the given owner(s).",
     )
-    category = IntegerInFilter(
-        help_text="Return only shows of the given category or categories.",
-    )
-    category__slug = filters.CharFilter(
-        field_name="category", help_text="Return only shows of the given category slug."
-    )
-    language = IntegerInFilter(
-        help_text="Return only shows of the given language(s).",
-    )
-    topic = IntegerInFilter(
+    topicIds = IntegerInFilter(
         help_text="Return only shows of the given topic(s).",
     )
-    topic__slug = filters.CharFilter(
+    topicSlug = filters.CharFilter(
         field_name="topic", help_text="Return only shows of the given topic slug."
     )
-    type = IntegerInFilter(
+    typeId = IntegerInFilter(
         help_text="Return only shows of a given type.",
     )
-    type__slug = filters.CharFilter(
+    typeSlug = filters.CharFilter(
         field_name="type", help_text="Return only shows of the given type slug."
     )
-    public = filters.BooleanFilter(
-        field_name="is_public",
-        help_text="Return only shows that are public/non-public.",
-    )
 
     def filter_active(self, queryset: QuerySet, name: str, value: bool):
         # Filter currently running shows
@@ -128,15 +128,19 @@ class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
     class Meta:
         model = models.Show
         fields = [
-            "active",
-            "category",
-            "host",
-            "language",
-            "music_focus",
-            "owner",
-            "public",
-            "topic",
-            "type",
+            "categoryIds",
+            "categorySlug",
+            "hostIds",
+            "isActive",
+            "isPublic",
+            "languageIds",
+            "musicFocusIds",
+            "musicFocusSlug",
+            "ownerIds",
+            "topicIds",
+            "topicSlug",
+            "typeId",
+            "typeSlug",
         ]
 
 
@@ -231,35 +235,45 @@ class TimeSlotFilterSet(filters.FilterSet):
 
 
 class NoteFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
-    show = IntegerInFilter(
-        field_name="timeslot__show",
-        help_text="Return only notes that belong to the specified show(s).",
-    )
-    timeslot = IntegerInFilter(
-        field_name="timeslot",
-        help_text="Return only notes that belong to the specified timeslot(s).",
-    )
     ids = IntegerInFilter(
         field_name="id",
         help_text="Return only notes matching the specified id(s).",
     )
-    show_owner = IntegerInFilter(
+    ownerIds = IntegerInFilter(
+        field_name="owner",
+        help_text="Return only notes that belong to the specified owner(s).",
+    )
+    showIds = IntegerInFilter(
+        field_name="timeslot__show",
+        help_text="Return only notes that belong to the specified show(s).",
+    )
+    showOwnerIds = 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(
+        field_name="timeslot",
+        help_text="Return only notes that belong to the specified timeslot(s).",
+    )
 
     class Meta:
         model = models.Note
         help_texts = {
-            "owner": "Return only notes created by the specified user.",
+            "ownerId": "Return only notes created by the specified user.",
         }
-        fields = ["ids", "owner", "show", "timeslot", "show_owner"]
+        fields = [
+            "ids",
+            "ownerIds",
+            "showIds",
+            "showOwnerIds",
+            "timeslotIds",
+        ]
 
 
 class ActiveFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
-    active = filters.BooleanFilter(field_name="is_active")
+    isActive = filters.BooleanFilter(field_name="is_active")
 
     class Meta:
         fields = [
-            "active",
+            "isActive",
         ]
diff --git a/program/views.py b/program/views.py
index 7c2e5960..520e6f27 100644
--- a/program/views.py
+++ b/program/views.py
@@ -381,8 +381,25 @@ class APIShowViewSet(DisabledObjectPermissionCheckMixin, viewsets.ModelViewSet):
 
     def list(self, request, *args, **kwargs):
         filter_kwargs = {}
+
         for key, value in request.query_params.items():
-            filter_kwargs[key] = value
+            #  map query parameters to filter names
+            if 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)
@@ -792,6 +809,46 @@ 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 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