Browse Source

sync narrators updated to latest changes

master
Mohsen Taba 3 weeks ago
parent
commit
534dc40adc
  1. 48
      apps/hadis/serializers/hadis.py
  2. 22
      apps/hadis/views/transmitter.py

48
apps/hadis/serializers/hadis.py

@ -575,8 +575,48 @@ class TransmitterSyncSerializer(serializers.ModelSerializer):
'description': get_localized_text(obj.description, request),
'thumbnail': obj.thumbnail.url if obj.thumbnail else None,
'share_link': obj.share_link,
'tadlis': obj.tadlis,
'ikhtilat': obj.ikhtilat,
'companion_type': obj.companion_type,
'relatives': self._get_relatives(obj, request),
}
def _get_relatives(self, obj, request):
relatives_qs = obj.relatives.all()
grouped = {}
for rel in relatives_qs:
rel_type = rel.relation_type
slug = rel.narrator.slug if rel.narrator else None
name = rel.name
if rel.narrator and not name:
name = get_localized_text(rel.narrator.full_name, request)
item = {
"name": name,
"slug": slug
}
if rel_type not in grouped:
grouped[rel_type] = {
"relation_value": get_localized_text(rel.relation_value, request) if rel.relation_value else None,
"arabic_relation_value": get_arabic_localized_text(rel.relation_value) if rel.relation_value else None,
"items": []
}
grouped[rel_type]["items"].append(item)
result = []
for rel_type, data in grouped.items():
result.append({
"relation_type": rel_type,
"relation_value": data["relation_value"],
"arabic_relation_value": data["arabic_relation_value"],
"members": data["items"]
})
return result
def get_scholars_opinions(self, obj):
"""Get all scholarly opinions about this transmitter"""
request = self.context.get('request') # ← FIX: Define request
@ -585,12 +625,14 @@ class TransmitterSyncSerializer(serializers.ModelSerializer):
{
'id': opinion.id,
'scholar_name': get_localized_text(opinion.scholar_name, request),
'arabic_scholar_name': get_arabic_localized_text(opinion.scholar_name),
'scholar': {
'id': opinion.scholar.id,
'name': get_localized_text(opinion.scholar.name, request),
'slug': opinion.scholar.slug
} if opinion.scholar else None,
'opinion_text': get_localized_text(opinion.opinion_text, request),
'arabic_opinion_text': get_arabic_localized_text(opinion.opinion_text),
'status': {
'id': opinion.status.id,
'title': get_localized_text(opinion.status.title, request),
@ -614,10 +656,8 @@ class TransmitterSyncSerializer(serializers.ModelSerializer):
).data
def get_hadis(self, obj):
# چون از related_name='hadises' در مدل HadisTransmitter استفاده شده،
# لیست تمام رکوردهای واسط را می‌گیریم.
# استفاده از set باعث می‌شود اگر یک راوی در ۲ سند از یک حدیث بود، آیدی آن حدیث تکراری نشود.
return list(set(item.hadis_id for item in obj.hadises.all() if item.hadis_id))
categories_map = self.context.get('categories_map', {})
return list(categories_map.get(int(obj.id), set()))
def get_relations(self, obj):
"""
استخراج آنی آیدی اساتید و شاگردان از کانتکست بدون اجرای کوئری اضافه

22
apps/hadis/views/transmitter.py

@ -132,7 +132,7 @@ class TransmitterSyncView(ListAPIView):
return self.list(request, *args, **kwargs)
def get_queryset(self):
from ..models import TransmitterOriginalText
from ..models import TransmitterOriginalText, TransmitterRelative
return (
Transmitters.objects
@ -152,28 +152,35 @@ class TransmitterSyncView(ListAPIView):
'references__images'
)
),
# این مورد را هم برای بهینگی حافظه رم لیمیت می‌کنیم تا کل فیلدها لود نشوند
Prefetch('hadises', queryset=HadisTransmitter.objects.only('id', 'hadis_id', 'transmitter_id'))
Prefetch('relatives', queryset=TransmitterRelative.objects.select_related('narrator'))
)
.order_by('id')
)
def list(self, request, *args, **kwargs):
# 🧠 ۱. واکشی لینک‌ها با values_list برای جلوگیری از هرگونه تداخل دیکشنری
# 🧠 ۱. واکشی لینک‌ها با values_list برای جلوگیری از هرگونه تداخل دیکشنری و افزایش سرعت
all_links = HadisTransmitter.objects.values_list(
'hadis_id', 'chain_index', 'order', 'transmitter_id'
'hadis_id', 'chain_index', 'order', 'transmitter_id', 'hadis__category_id'
)
# 🧠 ۲. بازسازی کل زنجیره‌های حدیثی به صورت کاملاً ایمن و عددی
chains = {}
for hadis_id, chain_index, order, transmitter_id in all_links:
categories_map = {}
for hadis_id, chain_index, order, transmitter_id, category_id in all_links:
if transmitter_id is None:
continue
tx_id = int(transmitter_id)
if tx_id not in categories_map:
categories_map[tx_id] = set()
if category_id is not None:
categories_map[tx_id].add(int(category_id))
key = (int(hadis_id), int(chain_index))
if key not in chains:
chains[key] = {}
chains[key][int(order)] = int(transmitter_id)
chains[key][int(order)] = tx_id
# دایرکتوری‌های نگاشت روابط
teachers_map = {}
@ -201,6 +208,7 @@ class TransmitterSyncView(ListAPIView):
context = self.get_serializer_context()
context['teachers_map'] = teachers_map
context['students_map'] = students_map
context['categories_map'] = categories_map
serializer = self.get_serializer_class()(
queryset,

Loading…
Cancel
Save