diff --git a/apps/hadis/serializers/hadis.py b/apps/hadis/serializers/hadis.py index de1b4c9..0bbf5e3 100644 --- a/apps/hadis/serializers/hadis.py +++ b/apps/hadis/serializers/hadis.py @@ -88,6 +88,7 @@ class HadisSyncSerializer(serializers.ModelSerializer): explanations = serializers.SerializerMethodField() corrections = serializers.SerializerMethodField() category_slug = serializers.CharField(source='category.slug', read_only=True) + interpretations = serializers.SerializerMethodField() title =LocalizedField() title_narrator = LocalizedField() translation = LocalizedField() @@ -98,7 +99,7 @@ class HadisSyncSerializer(serializers.ModelSerializer): # header (no-extend) 'id', 'number', 'slug', 'category_id', 'category_slug', 'title', 'title_narrator', 'text', 'translation', # grouped sections - 'detail', 'narrators', 'explanations', 'corrections', + 'detail', 'narrators', 'explanations', 'corrections', 'interpretations' ] def get_detail(self, obj): @@ -230,17 +231,23 @@ class HadisSyncSerializer(serializers.ModelSerializer): return explanations_list if explanations_list else None def get_corrections(self, obj): - request = self.context.get('request') - corrections_data = [] - for correction in obj.hadiscorrection_set.all(): - corrections_data.append({ - 'id': correction.id, - 'title': get_localized_text(correction.title, request), - 'description': get_localized_correction_text(correction.text, request=request), - 'translation': get_localized_text(correction.translation, request), - 'share_link': correction.share_link, - }) - return corrections_data + """گرفتن لیست کامل تصحیحات با تمام جزئیات و رفرنس‌ها""" + # استفاده از سریالایزر Detail که در مرحله قبل ساختیم + return HadisCorrectionDetailSerializer( + obj.hadiscorrection_set.all(), + many=True, + context=self.context + ).data + + def get_interpretations(self, obj): + """گرفتن لیست کامل تفاسیر متصل به دسته‌بندی این حدیث با جزئیات کامل""" + if obj.category: + return HadisInterpretationDetailSerializer( + obj.category.interpretations.all(), + many=True, + context=self.context + ).data + return [] class HadisListSerializer(serializers.ModelSerializer): """Serializer for Hadis list""" @@ -524,19 +531,14 @@ class TransmitterSyncSerializer(serializers.ModelSerializer): ] def get_original_texts(self, obj): - """Get original texts of the transmitter""" - request = self.context.get('request') # ← FIX: Define request + """گرفتن متون اصلی راوی با جزئیات کامل و رفرنس‌ها""" + # استفاده از سریالایزر Detail که در مرحله قبل ساختیم + return TransmitterOriginalTextDetailSerializer( + obj.originaltexts.all(), + many=True, + context=self.context + ).data - return [ - { - 'id': t.id, - 'title': get_localized_text(t.title, request), - 'text': get_localized_text(t.text, request), - 'translation': get_localized_text(t.translation, request), - 'share_link': t.share_link, - } - for t in obj.originaltexts.all() # Already prefetched - ] def get_hadis(self, obj): # چون از related_name='hadises' در مدل HadisTransmitter استفاده شده، # لیست تمام رکوردهای واسط را می‌گیریم. diff --git a/apps/hadis/views/hadis.py b/apps/hadis/views/hadis.py index 66d3a0e..cedd873 100644 --- a/apps/hadis/views/hadis.py +++ b/apps/hadis/views/hadis.py @@ -106,30 +106,46 @@ class HadisSyncView(ListAPIView): .select_related('category', 'hadis_status') .prefetch_related( 'tags', - # 1. OPTIMIZED TRANSMITTERS Prefetch( 'transmitters', queryset=HadisTransmitter.objects.select_related( 'transmitter', - 'transmitter__reliability', # <--- Fixes N+1 for reliability text + 'transmitter__reliability', 'narrator_layer' ).order_by('order') ), - # 2. OPTIMIZED REFERENCES Prefetch( 'references', queryset=HadisReference.objects .select_related('book_reference') .prefetch_related( 'book_reference__authors', - # <--- Fixes N+1 for Image ordering Prefetch( 'images', queryset=ReferenceImage.objects.order_by('priority') ) ) ), - 'hadiscorrection_set', + # 👇 اضافه شدن واکشی عمیق برای تصحیحات + Prefetch( + 'hadiscorrection_set', + queryset=HadisCorrection.objects.prefetch_related( + 'references__book_reference__authors', + 'references__edition', + 'references__book_volume', + 'references__images' + ) + ), + # 👇 اضافه شدن واکشی عمیق برای تفاسیر + Prefetch( + 'category__interpretations', + queryset=HadisInterpretation.objects.prefetch_related( + 'references__book_reference__authors', + 'references__edition', + 'references__book_volume', + 'references__images' + ) + ), ) .order_by('id') ) diff --git a/apps/hadis/views/transmitter.py b/apps/hadis/views/transmitter.py index 8fe5b5b..b3a2207 100644 --- a/apps/hadis/views/transmitter.py +++ b/apps/hadis/views/transmitter.py @@ -132,12 +132,28 @@ class TransmitterSyncView(ListAPIView): return self.list(request, *args, **kwargs) def get_queryset(self): + from ..models import TransmitterOriginalText + return ( Transmitters.objects + # 👇 ۱. واکشی اطلاعات reliability راوی در همان کوئری اصلی + .select_related('reliability') .prefetch_related( - Prefetch('opinions', queryset=TransmitterOpinion.objects.select_related('status')), - Prefetch('originaltexts', queryset=TransmitterOriginalText.objects.all()), - 'hadises' + # 👇 ۲. اضافه کردن 'scholar' برای جلوگیری از کوئری اضافه در نظرات دانشمندان + Prefetch('opinions', queryset=TransmitterOpinion.objects.select_related('status', 'scholar')), + + Prefetch( + 'originaltexts', + # 👇 ۳. اضافه کردن 'transmitter' برای جلوگیری از کوئری چرخشی در DetailSerializer متون اصلی + queryset=TransmitterOriginalText.objects.select_related('transmitter').prefetch_related( + 'references__book_reference__authors', + 'references__edition', + 'references__book_volume', + 'references__images' + ) + ), + # این مورد را هم برای بهینگی حافظه رم لیمیت می‌کنیم تا کل فیلدها لود نشوند + Prefetch('hadises', queryset=HadisTransmitter.objects.only('id', 'hadis_id', 'transmitter_id')) ) .order_by('id') )