From 7eda86bbc33ca424c3d2c9c47c05ead4826c3fde Mon Sep 17 00:00:00 2001 From: mohsentaba Date: Mon, 6 Apr 2026 08:49:28 +0330 Subject: [PATCH] resolve performance issue of book reference hadiths using pagination for hadiths. --- apps/hadis/serializers/reference.py | 33 ++++++++++++++++++++++++++--- apps/hadis/views/reference.py | 15 ++++++++----- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/apps/hadis/serializers/reference.py b/apps/hadis/serializers/reference.py index ed3c0c3..4e37389 100644 --- a/apps/hadis/serializers/reference.py +++ b/apps/hadis/serializers/reference.py @@ -1,4 +1,5 @@ from rest_framework import serializers +from rest_framework.pagination import PageNumberPagination from django.utils.translation import get_language from .category import get_localized_text @@ -115,9 +116,35 @@ class BookDetailSerializer(serializers.ModelSerializer): fields = ['id','title','rate','isbn','share_link','language','number_page','publisher','description','volume','slug','attribute','author','image','hadis'] def get_hadis(self,obj): - references = obj.hadis_references.all() - hadis_list = [ref.hadis for ref in references if ref.hadis] - return HadisListSerializer(hadis_list,many=True, context=self.context).data + from apps.hadis.models import Hadis + # 1. Fetch related hadis QuerySet for better pagination efficiency + # We filter by status=True to ensure only visible hadises are returned + hadis_ids = obj.hadis_references.values_list('hadis', flat=True) + hadis_qs = Hadis.objects.filter(id__in=hadis_ids, status=True).order_by('id') + + # 2. Initialize Pagination + paginator = PageNumberPagination() + paginator.page_size = 20 # Requirements: 20 per page + + request = self.context.get("request") + + # 3. Paginate the QuerySet + paginated_hadis = paginator.paginate_queryset(hadis_qs, request) + + if paginated_hadis is not None: + # 4. Serialize paginated items + serializer = HadisListSerializer(paginated_hadis, many=True, context=self.context) + + # 5. Build paginated response structure + return { + 'count': paginator.page.paginator.count, + 'next': paginator.get_next_link(), + 'previous': paginator.get_previous_link(), + 'results': serializer.data + } + + # Fallback + return HadisListSerializer(hadis_qs, many=True, context=self.context).data diff --git a/apps/hadis/views/reference.py b/apps/hadis/views/reference.py index a0d5912..f5f0ba4 100644 --- a/apps/hadis/views/reference.py +++ b/apps/hadis/views/reference.py @@ -69,11 +69,16 @@ class BookDetailView(RetrieveAPIView): return super().get(request, *args, **kwargs) def get_queryset(self): - return BookReference.objects.filter(slug = self.kwargs.get('reference_slug')) - # .prefetch_related( - # 'authors__name', - # 'images__image', - # ) + return ( + BookReference.objects + .filter(slug = self.kwargs.get('reference_slug')) + .prefetch_related( + 'attributes', + 'authors', + 'images', + 'hadis_references__hadis' + ) + ) from django.db.models import Prefetch