|
|
|
@ -11,6 +11,8 @@ from ..serializers.category import get_localized_text |
|
|
|
from ..models import Transmitters, HadisCategory, Hadis, HadisCollection,HadisTransmitter , HadisCorrection ,HadisReference, HadisStatus ,ReferenceImage |
|
|
|
from ..serializers import HadisListSerializer, HadisBasicSerializer, HadisDetailSerializer, HadisCollectionListSerializer, HadisSyncSerializer,HadisCorrectionSerializer,HadisTransmitterListSerializer , SimpleCategory, NarratorLayerSerializer , PinnedHadisCollectionSerializer |
|
|
|
from ..docs import arguments_filters_swagger ,hadis_list_swagger, hadis_detail_swagger, hadis_collections_swagger, hadis_sync_swagger, hadis_transmitters_swagger, hadis_corrections_swagger, hadis_basic_swagger, hadis_main_list_swagger, hadis_layers_swagger |
|
|
|
from django.db.models import Q |
|
|
|
from ..serializers.category import get_localized_text |
|
|
|
|
|
|
|
from rest_framework import status |
|
|
|
|
|
|
|
@ -161,9 +163,6 @@ class HadisListView(ListAPIView): |
|
|
|
def get(self, request, *args, **kwargs): |
|
|
|
return self.list(request, *args, **kwargs) |
|
|
|
|
|
|
|
def get(self, request, *args, **kwargs): |
|
|
|
return self.list(request, *args, **kwargs) |
|
|
|
|
|
|
|
def list(self, request, *args, **kwargs): |
|
|
|
# 1. Run the standard list logic (get pagination, filter, results) |
|
|
|
response = super().list(request, *args, **kwargs) |
|
|
|
@ -175,18 +174,15 @@ class HadisListView(ListAPIView): |
|
|
|
# 3. Serialize this single category for the Hero section |
|
|
|
category_data = SimpleCategory(category_obj).data |
|
|
|
|
|
|
|
# 👇 4. NEW LOGIC: Check if it's a Quran Category and fetch verse data |
|
|
|
# 4. Check if it's a Quran Category and fetch verse data |
|
|
|
quran_data = None |
|
|
|
if category_obj.source_type == HadisCategory.SourceType.QURAN: |
|
|
|
# سعی میکنیم آبجکت قرآن متصل به این کتگوری رو بگیریم |
|
|
|
try: |
|
|
|
# استفاده از prefetch_related برای ترجمههای ثانویه جهت جلوگیری از N+1 |
|
|
|
from ..models.category import CategoryQuranVerse |
|
|
|
verse_obj = CategoryQuranVerse.objects.prefetch_related( |
|
|
|
'secondary_translations' |
|
|
|
).get(category=category_obj) |
|
|
|
|
|
|
|
# سریالایز کردن دیتای قرآن (با کانتکست ریکوئست برای زبان) |
|
|
|
from ..serializers.category import CategoryQuranVerseSerializer |
|
|
|
quran_data = CategoryQuranVerseSerializer( |
|
|
|
verse_obj, |
|
|
|
@ -195,7 +191,20 @@ class HadisListView(ListAPIView): |
|
|
|
except CategoryQuranVerse.DoesNotExist: |
|
|
|
pass |
|
|
|
|
|
|
|
# 5. Inject it into the response data |
|
|
|
# 👇 5. NEW LOGIC: Fetch all statuses for frontend filtering UI |
|
|
|
lang = getattr(request, "LANGUAGE_CODE", None) or "fa" |
|
|
|
statuses_list = [ |
|
|
|
{ |
|
|
|
"id": status.id, |
|
|
|
"slug": status.slug, |
|
|
|
"title": get_localized_text(status.title, request=request, language_code=lang) or "", |
|
|
|
"color": status.color, |
|
|
|
"main_color_code": status.main_color_code, |
|
|
|
} |
|
|
|
for status in HadisStatus.objects.all().order_by('order') |
|
|
|
] |
|
|
|
|
|
|
|
# 6. Inject it into the response data |
|
|
|
if isinstance(response.data, dict): |
|
|
|
ordered_data = {} |
|
|
|
for key in ['count', 'next', 'previous']: |
|
|
|
@ -203,10 +212,11 @@ class HadisListView(ListAPIView): |
|
|
|
ordered_data[key] = response.data[key] |
|
|
|
|
|
|
|
ordered_data['current_category'] = category_data |
|
|
|
|
|
|
|
# 👇 دیتای قرآن را تزریق میکنیم |
|
|
|
ordered_data['quran_data'] = quran_data |
|
|
|
|
|
|
|
# 👇 تزریق لیست استاتوسها قبل از نتایج |
|
|
|
ordered_data['statuses'] = statuses_list |
|
|
|
|
|
|
|
if 'results' in response.data: |
|
|
|
ordered_data['results'] = response.data['results'] |
|
|
|
response.data = ordered_data |
|
|
|
@ -222,12 +232,36 @@ class HadisListView(ListAPIView): |
|
|
|
category__slug=category_slug, |
|
|
|
status=True |
|
|
|
).annotate( |
|
|
|
# distinct=True is CRITICAL here. |
|
|
|
# Without it, if 3 narrators are from "Layer 1", it counts as 3. |
|
|
|
# With it, it counts as 1 (unique layer). |
|
|
|
layer_count=Count('transmitters__narrator_layer', distinct=True) |
|
|
|
).select_related('category') |
|
|
|
|
|
|
|
# 👇 1. Apply Search Filter |
|
|
|
search_query = self.request.query_params.get('search', None) |
|
|
|
if search_query: |
|
|
|
search_conditions = Q(text__icontains=search_query) |
|
|
|
search_conditions |= Q(title__icontains=search_query) |
|
|
|
search_conditions |= Q(title_narrator__icontains=search_query) |
|
|
|
search_conditions |= Q(translation__icontains=search_query) |
|
|
|
queryset = queryset.filter(search_conditions) |
|
|
|
|
|
|
|
# 👇 2. Apply Status Filter (Supports multiple comma-separated slugs) |
|
|
|
status_filter = self.request.query_params.get('status', None) |
|
|
|
if status_filter: |
|
|
|
status_slugs = [s.strip() for s in status_filter.split(',')] |
|
|
|
queryset = queryset.filter(hadis_status__slug__in=status_slugs) |
|
|
|
|
|
|
|
# 👇 3. Apply Transmitter Filter (Supports multiple comma-separated slugs) |
|
|
|
transmitter_filter = self.request.query_params.get('transmitter', None) |
|
|
|
if transmitter_filter: |
|
|
|
transmitter_slugs = [t.strip() for t in transmitter_filter.split(',')] |
|
|
|
queryset = queryset.filter(transmitters__transmitter__slug__in=transmitter_slugs) |
|
|
|
|
|
|
|
# 👇 4. Apply Source Filter (Supports multiple comma-separated slugs) |
|
|
|
source_filter = self.request.query_params.get('source', None) |
|
|
|
if source_filter: |
|
|
|
source_slugs = [s.strip() for s in source_filter.split(',')] |
|
|
|
queryset = queryset.filter(references__book_reference__slug__in=source_slugs) |
|
|
|
|
|
|
|
# Filter by bookmarks if provided |
|
|
|
is_bookmark = self.request.query_params.get('is_bookmark', '').lower() |
|
|
|
if is_bookmark == 'true' and self.request.user.is_authenticated: |
|
|
|
@ -239,7 +273,8 @@ class HadisListView(ListAPIView): |
|
|
|
).values_list('content_id', flat=True) |
|
|
|
queryset = queryset.filter(id__in=bookmarked_ids) |
|
|
|
|
|
|
|
return queryset |
|
|
|
# ❗️ distinct() برای جلوگیری از دابلیکیت شدن احادیث به خاطر ManyToMany ها الزامی است |
|
|
|
return queryset.distinct() |
|
|
|
|
|
|
|
def get_serializer_context(self): |
|
|
|
"""Add user bookmarks to serializer context to avoid caching issues""" |
|
|
|
|