diff --git a/program/filters.py b/program/filters.py index 823ed52e38ecd1435828b37db744f1816774815a..b588795aea8207b11544b48008529fd865d81ae6 100644 --- a/program/filters.py +++ b/program/filters.py @@ -39,17 +39,23 @@ class IntegerInFilter(filters.BaseInFilter): class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet): - categoryIds = IntegerInFilter( + order = filters.OrderingFilter( + fields=["name", "id", "is_active", "is_owner"], + help_text="Order shows by the given field(s).", + ) + 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,37 +63,48 @@ 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_queryset(self, queryset): + _id = getattr(self.request.user, "id", None) + queryset = queryset.annotate(is_owner=Q(owners=_id)) + return super().filter_queryset(queryset) + def filter_active(self, queryset: QuerySet, name: str, value: bool): # Filter currently running shows # Get currently running schedules to filter by first @@ -116,31 +133,23 @@ 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", + "order", + "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 +183,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 +250,8 @@ class TimeSlotFilterSet(filters.FilterSet): "start", "end", "surrounding", + "schedule_ids", + "show_ids", ] @@ -249,41 +260,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 ecdabf3e1ced2e7abafb26850ee47fa721db0a26..6012b1ef9e200fab23676f2e42c9d4726dcaf87a 100644 --- a/program/views.py +++ b/program/views.py @@ -32,11 +32,11 @@ 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 django_filters.rest_framework import DjangoFilterBackend from program import filters from program.models import ( Category, @@ -374,43 +374,9 @@ class APIShowViewSet(DisabledObjectPermissionCheckMixin, viewsets.ModelViewSet): serializer_class = ShowSerializer permission_classes = [permissions.DjangoModelPermissionsOrAnonReadOnly] pagination_class = LimitOffsetPagination + filter_backends = [DjangoFilterBackend, drf_filters.SearchFilter] 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) + search_fields = ["name", "slug", "short_description", "description"] def get_object(self): queryset = self.filter_queryset(self.get_queryset()) @@ -808,49 +774,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()