From 25c48252eb2527a27a643d641b6c8abc9f2852ee Mon Sep 17 00:00:00 2001 From: ZachBurke04652 Date: Mon, 16 Jun 2025 13:51:20 -0400 Subject: [PATCH 1/3] Update views.py In the SpeciesViewSet class added a list function that handles pagination --- app/data/views.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/app/data/views.py b/app/data/views.py index 2243a8d..32b710b 100644 --- a/app/data/views.py +++ b/app/data/views.py @@ -45,6 +45,8 @@ from django.conf import settings from rest_framework_simplejwt.authentication import JWTAuthentication from rest_framework.parsers import MultiPartParser +from data.pagination import Pagination +from rest_framework.response import Response from_email = settings.EMAIL_HOST_USER @@ -290,8 +292,40 @@ class SpeciesViewSet(BaseApprovalViewSet): serializer_class = serializers.SpeciesSerializer queryset = Species.objects.all() authentication_classes = [JWTAuthentication] + pagination_class = Pagination filter_backends = (filters.DjangoFilterBackend,) filterset_fields = ("status", "uploaded_by", "selfies", "smiles") + + def list(self, request, *args, **kwargs): + """Custom list to support page ranges like 1-3.""" + page_param = request.query_params.get("page", "1") + page_size = self.pagination_class.page_size or 20 # Default to 20 + + try: + if "-" in page_param: + start, end = map(int, page_param.split("-")) + if start > end or start < 1: + raise ValueError("Invalid range") + start_index = (start - 1) * page_size + end_index = end * page_size + else: + page = int(page_param) + start_index = (page - 1) * page_size + end_index = page * page_size + except Exception: + return Response({"error": "Invalid page format. Use ?page=2 or ?page=1-3"}, status=400) + + # Apply filters manually using DRF's get_queryset() + qs = self.filter_queryset(self.get_queryset()) + total_count = qs.count() + sliced = qs[start_index:end_index] + serializer = self.get_serializer(sliced, many=True) + + return Response({ + "count": total_count, + "results": serializer.data, + "range": f"{start_index + 1}–{min(end_index, total_count)}" + }) def get_permissions(self): """No authentication required for GET requests.""" @@ -1139,4 +1173,4 @@ def get(self, request, user_id: int, format=None): "pending": total_length_pending, # Changed key name "unapproved_counts": list(unapproved_counts), } - ) \ No newline at end of file + ) From 80d6bedeb50ab0be8ddcf219101497cfde4dfd64 Mon Sep 17 00:00:00 2001 From: ZachBurke04652 Date: Mon, 16 Jun 2025 13:52:26 -0400 Subject: [PATCH 2/3] Added pagination model Model to handle pagination --- app/data/pagination.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 app/data/pagination.py diff --git a/app/data/pagination.py b/app/data/pagination.py new file mode 100644 index 0000000..625fb62 --- /dev/null +++ b/app/data/pagination.py @@ -0,0 +1,33 @@ +from rest_framework.pagination import PageNumberPagination +from rest_framework.response import Response + +class Pagination(PageNumberPagination): + """Species Pagination""" + page_query_param = 'page' + page_size = 20 + + def paginate_queryset(self, queryset, request, view=None): + page_param = request.query_params.get(self.page_query_param, '1') + + if '-' in page_param: + try: + start, end = map(int, page_param.split('-')) + if start < 1 or end < start: + return [] + start_index = (start - 1) * self.page_size + end_index = end * self.page_size + self.page = queryset[start_index:end_index] # ✅ FIXED + return self.page + except ValueError: + return [] + else: + return super().paginate_queryset(queryset, request, view) + + def get_paginated_response(self, data): + if hasattr(self, 'page') and self.page is not None: + return super().get_paginated_response(data) + else: + return Response({ + "count": len(data), + "results": data + }) From e37ccd9936c5527b9841120325f0c46da1d7eca6 Mon Sep 17 00:00:00 2001 From: ZachBurke04652 Date: Mon, 16 Jun 2025 13:54:16 -0400 Subject: [PATCH 3/3] Update settings.py In REST_FRAMEWORK, added default pagination class and page size --- app/app/settings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/app/settings.py b/app/app/settings.py index 158a157..646c395 100644 --- a/app/app/settings.py +++ b/app/app/settings.py @@ -157,6 +157,8 @@ # for enabling swagger REST_FRAMEWORK = { "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", + "DEFAULT_PAGINATION_CLASS": 'data.pagination.Pagination', + "PAGE_SIZE": 20, "DEFAULT_AUTHENTICATION_CLASSES": [ # "rest_framework.authentication.BasicAuthentication", # "rest_framework.authentication.SessionAuthentication",