From cb227c6daf76b51f3c18d3a46de18fbbacb2c84e Mon Sep 17 00:00:00 2001 From: Corban-Lee Jones Date: Sat, 2 Nov 2024 00:28:39 +0000 Subject: [PATCH] custom content filter backend --- apps/api/views.py | 64 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/apps/api/views.py b/apps/api/views.py index 7d72290..9b6f21a 100644 --- a/apps/api/views.py +++ b/apps/api/views.py @@ -2,12 +2,14 @@ import logging +from django.db.models import Q from django_filters import rest_framework as rest_filters from rest_framework import permissions, filters, generics, status from rest_framework.response import Response from rest_framework.pagination import PageNumberPagination from rest_framework.authentication import SessionAuthentication, TokenAuthentication from rest_framework.parsers import MultiPartParser, FormParser +from rest_framework.filters import BaseFilterBackend from apps.home.models import ( Server, @@ -39,6 +41,7 @@ class DefaultPagination(PageNumberPagination): """Default class for pagination in API views.""" page_size = 10 + page_query_param = "page" page_size_query_param = "page_size" max_page_size = 25 @@ -223,11 +226,66 @@ class Subscription_DetailView(ChangableDetailView): # region Content + +class ContentFilterBackend(BaseFilterBackend): + """ + If `match_any=true` in querystring, matches 'any' params instead + of 'all' params. + """ + + _MATCH_ANY_PARAM = "match_any" + _PAGINATION_PARAMS = [ + DefaultPagination.page_query_param, + DefaultPagination.page_size_query_param + ] + _SUB_PARAM = "subscription" + + def filter_queryset(self, request, queryset, view): + match_any = request.query_params.get(self._MATCH_ANY_PARAM) == "true" + filters = Q() + + for param, value in request.query_params.items(): + if param == self._MATCH_ANY_PARAM or param in self._PAGINATION_PARAMS: + continue + + query = Q(**{param: value}) + + if match_any and param != self._SUB_PARAM: + filters |= query + else: + filters &= query + + return queryset.filter(filters) + + class Content_ListView(ListCreateView): - filterset_fields = ("id", "subscription", "subscription__server", "item_id", "item_guid", "item_url", "item_title", "item_content_hash") - search_fields = ("item_id", "item_guid", "item_url", "item_title", "item_content_hash") - ordering_fields = ("id", "subscription", "item_id", "item_guid", "item_url", "item_title", "item_content_hash") + search_fields = ( + "subscription", + "subscription__server", + "item_id", + "item_guid", + "item_url", + "item_title", + "item_description", + "item_content_hash", + "item_image_url", + "item_thumbnail_url", + "item_published", + "item_author", + "item_author_url", + "item_feed_title", + "item_feed_url" + ) + filterset_fields = search_fields + ("id",) + ordering_fields = filterset_fields serializer_class = ContentSerializer + filter_backends = [ + ContentFilterBackend, + filters.SearchFilter, + rest_filters.DjangoFilterBackend, + filters.OrderingFilter + ] + # filter_backends = (FlexibleFilterBackend,) def get_queryset(self): if self.request.user.is_superuser: