|
|
|
@ -366,6 +366,9 @@ class HadisListView(ListAPIView): |
|
|
|
search_conditions |= Q(title_narrator__icontains=search_query) |
|
|
|
search_conditions |= Q(translation__icontains=search_query) |
|
|
|
search_conditions |= Q(tags__title__icontains=search_query) |
|
|
|
search_conditions |= Q(references__book_reference__title__icontains=search_query) |
|
|
|
search_conditions |= Q(transmitters__transmitter__full_name__icontains=search_query) |
|
|
|
search_conditions |= Q(transmitters__transmitter__known_as__icontains=search_query) |
|
|
|
queryset = queryset.filter(search_conditions) |
|
|
|
|
|
|
|
# 👇 2. Apply Status Filter (Supports multiple comma-separated slugs) |
|
|
|
@ -448,7 +451,7 @@ class HadisListView(ListAPIView): |
|
|
|
|
|
|
|
class HadisMainListView(ListAPIView): |
|
|
|
""" |
|
|
|
API view to list Hadis by category_id |
|
|
|
API view to list Hadis globally with comprehensive filtering |
|
|
|
""" |
|
|
|
serializer_class = HadisListSerializer |
|
|
|
authentication_classes = [TokenAuthentication] |
|
|
|
@ -460,7 +463,12 @@ class HadisMainListView(ListAPIView): |
|
|
|
return self.list(request, *args, **kwargs) |
|
|
|
|
|
|
|
def get_queryset(self): |
|
|
|
queryset = Hadis.objects.select_related('category__sect', 'hadis_status').prefetch_related( |
|
|
|
queryset = Hadis.objects.filter(status=True).select_related( |
|
|
|
'category__sect', 'hadis_status' |
|
|
|
).annotate( |
|
|
|
layer_count=Count('transmitters__narrator_layer', distinct=True) |
|
|
|
).prefetch_related( |
|
|
|
'tags', |
|
|
|
Prefetch( |
|
|
|
'references', |
|
|
|
queryset=HadisReference.objects.select_related( |
|
|
|
@ -478,21 +486,58 @@ class HadisMainListView(ListAPIView): |
|
|
|
|
|
|
|
# Get search parameters |
|
|
|
search_query = self.request.query_params.get('search', None) |
|
|
|
sect_filter = self.request.query_params.get('sect', None) or self.request.query_params.get('sect_type', None) |
|
|
|
source_type_filter = self.request.query_params.get('source_type', None) |
|
|
|
status_filter = self.request.query_params.get('status', None) |
|
|
|
category_filter = self.request.query_params.get('category', None) |
|
|
|
author_filter = self.request.query_params.get('author', None) or self.request.query_params.get('source_author', None) |
|
|
|
source_filter = self.request.query_params.get('source', None) |
|
|
|
category_filter = self.request.query_params.get('category', None) or self.request.query_params.get('category_slug', None) |
|
|
|
tag_filter = self.request.query_params.get('tag', None) or self.request.query_params.get('tags', None) |
|
|
|
|
|
|
|
# Apply search filter |
|
|
|
if search_query: |
|
|
|
queryset = self.apply_search_filter(queryset, search_query) |
|
|
|
|
|
|
|
# Apply status filter |
|
|
|
# Apply sect filter (e.g. shia, sunni) |
|
|
|
if sect_filter: |
|
|
|
sects = [s.strip().lower() for s in sect_filter.split(',') if s.strip()] |
|
|
|
if sects: |
|
|
|
queryset = queryset.filter(category__sect__sect_type__in=sects) |
|
|
|
|
|
|
|
# Apply source_type filter (e.g. hadith, quran, history, fatwa, quote) |
|
|
|
if source_type_filter: |
|
|
|
source_types = [st.strip().lower() for st in source_type_filter.split(',') if st.strip()] |
|
|
|
if source_types: |
|
|
|
queryset = queryset.filter(category__source_type__in=source_types) |
|
|
|
|
|
|
|
# Apply status filter (by slug or title) |
|
|
|
if status_filter: |
|
|
|
queryset = queryset.filter(hadis_status__title__icontains=status_filter) |
|
|
|
status_items = [s.strip() for s in status_filter.split(',') if s.strip()] |
|
|
|
queryset = queryset.filter( |
|
|
|
Q(hadis_status__slug__in=status_items) | Q(hadis_status__title__icontains=status_filter) |
|
|
|
) |
|
|
|
|
|
|
|
# Apply author filter |
|
|
|
if author_filter: |
|
|
|
author_slugs = [a.strip() for a in author_filter.split(',') if a.strip()] |
|
|
|
author_q = Q(references__book_reference__author__slug__in=author_slugs) |
|
|
|
numeric_ids = [int(a) for a in author_slugs if a.isdigit()] |
|
|
|
if numeric_ids: |
|
|
|
author_q |= Q(references__book_reference__author_id__in=numeric_ids) |
|
|
|
queryset = queryset.filter(author_q) |
|
|
|
|
|
|
|
# Apply source filter (reference books) |
|
|
|
if source_filter: |
|
|
|
source_slugs = [s.strip() for s in source_filter.split(',') if s.strip()] |
|
|
|
if source_slugs: |
|
|
|
queryset = queryset.filter(references__book_reference__slug__in=source_slugs) |
|
|
|
|
|
|
|
# Apply category filter |
|
|
|
if category_filter: |
|
|
|
queryset = queryset.filter(category__title__icontains=category_filter) |
|
|
|
cat_items = [c.strip() for c in category_filter.split(',') if c.strip()] |
|
|
|
queryset = queryset.filter( |
|
|
|
Q(category__slug__in=cat_items) | Q(category__title__icontains=category_filter) |
|
|
|
) |
|
|
|
|
|
|
|
# Apply tag filter |
|
|
|
if tag_filter: |
|
|
|
@ -518,7 +563,23 @@ class HadisMainListView(ListAPIView): |
|
|
|
).values_list('content_id', flat=True) |
|
|
|
queryset = queryset.filter(id__in=bookmarked_ids) |
|
|
|
|
|
|
|
return queryset |
|
|
|
return queryset.distinct() |
|
|
|
|
|
|
|
def get_serializer_context(self): |
|
|
|
"""Add user bookmarks to serializer context to avoid caching issues""" |
|
|
|
context = super().get_serializer_context() |
|
|
|
user = self.request.user |
|
|
|
if user.is_authenticated: |
|
|
|
from apps.bookmark.models.bookmark import Bookmark |
|
|
|
user_bookmarks = Bookmark.objects.filter( |
|
|
|
user=user, |
|
|
|
service=Bookmark.ServiceChoices.HADITH, |
|
|
|
status=True |
|
|
|
).values_list('content_id', flat=True) |
|
|
|
context['user_bookmarked_hadis_ids'] = set(user_bookmarks) |
|
|
|
else: |
|
|
|
context['user_bookmarked_hadis_ids'] = set() |
|
|
|
return context |
|
|
|
|
|
|
|
def list(self, request, *args, **kwargs): |
|
|
|
queryset = self.get_queryset() |
|
|
|
@ -528,19 +589,7 @@ class HadisMainListView(ListAPIView): |
|
|
|
if page is not None: |
|
|
|
serializer = self.get_serializer(page, many=True) |
|
|
|
paginated_response = self.get_paginated_response(serializer.data) |
|
|
|
|
|
|
|
# Get category titles |
|
|
|
category_titles = self.get_category_titles(request) |
|
|
|
|
|
|
|
# Get status titles |
|
|
|
status_titles = self.get_status_titles(request) |
|
|
|
|
|
|
|
# Modify the paginated response to include our custom data |
|
|
|
response_data = paginated_response.data |
|
|
|
# response_data['category_titles'] = self.get_cached_category_titles(request) |
|
|
|
# response_data['status_titles'] = self.get_cached_status_titles(request) |
|
|
|
|
|
|
|
return Response(response_data) |
|
|
|
return Response(paginated_response.data) |
|
|
|
|
|
|
|
# Fallback for when pagination is disabled |
|
|
|
serializer = self.get_serializer(queryset, many=True) |
|
|
|
@ -549,8 +598,6 @@ class HadisMainListView(ListAPIView): |
|
|
|
'results': serializer.data |
|
|
|
}) |
|
|
|
|
|
|
|
return Response(response_data) |
|
|
|
|
|
|
|
def get_category_titles(self,request): |
|
|
|
"""Get list of category titles based on language""" |
|
|
|
from ..models import HadisCategory |
|
|
|
@ -579,7 +626,7 @@ class HadisMainListView(ListAPIView): |
|
|
|
def apply_search_filter(self, queryset, search_query): |
|
|
|
""" |
|
|
|
Apply search filter across multiple fields including JSONFields. |
|
|
|
Searches in: title, title_narrator, text, translation |
|
|
|
Searches in: title, title_narrator, text, translation, tags, book references, transmitters |
|
|
|
""" |
|
|
|
from django.db.models import Q |
|
|
|
|
|
|
|
@ -592,6 +639,9 @@ class HadisMainListView(ListAPIView): |
|
|
|
search_conditions |= Q(title_narrator__icontains=search_query) |
|
|
|
search_conditions |= Q(translation__icontains=search_query) |
|
|
|
search_conditions |= Q(tags__title__icontains=search_query) |
|
|
|
search_conditions |= Q(references__book_reference__title__icontains=search_query) |
|
|
|
search_conditions |= Q(transmitters__transmitter__full_name__icontains=search_query) |
|
|
|
search_conditions |= Q(transmitters__transmitter__known_as__icontains=search_query) |
|
|
|
|
|
|
|
return queryset.filter(search_conditions) |
|
|
|
|
|
|
|
|