|
|
@ -72,15 +72,152 @@ class HadisSyncView(ListAPIView): |
|
|
return self.list(request, *args, **kwargs) |
|
|
return self.list(request, *args, **kwargs) |
|
|
|
|
|
|
|
|
def list(self, request, *args, **kwargs): |
|
|
def list(self, request, *args, **kwargs): |
|
|
|
|
|
from django.utils.translation import get_language |
|
|
|
|
|
|
|
|
|
|
|
# 1. PRE-FETCH DATA ONCE |
|
|
queryset = self.get_queryset() |
|
|
queryset = self.get_queryset() |
|
|
serializer = self.get_serializer(queryset, many=True) |
|
|
|
|
|
|
|
|
|
|
|
response_data = { |
|
|
|
|
|
'count': queryset.count(), |
|
|
|
|
|
'results': serializer.data |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
# Get language once for the entire bulk operation |
|
|
|
|
|
lang = getattr(request, "LANGUAGE_CODE", None) or get_language() or "en" |
|
|
|
|
|
|
|
|
|
|
|
# Pre-calculate base URL for images |
|
|
|
|
|
media_url = request.build_absolute_uri('/')[:-1] # Remove trailing slash |
|
|
|
|
|
|
|
|
|
|
|
results = [] |
|
|
|
|
|
for obj in queryset: |
|
|
|
|
|
# --- Detail Block --- |
|
|
|
|
|
status_block = None |
|
|
|
|
|
if obj.hadis_status: |
|
|
|
|
|
status_block = { |
|
|
|
|
|
'id': obj.hadis_status.id, |
|
|
|
|
|
'title': get_localized_text(obj.hadis_status.title, language_code=lang), |
|
|
|
|
|
'color': obj.hadis_status.color, |
|
|
|
|
|
'main_color_code': obj.hadis_status.main_color_code, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
tags_block = [ |
|
|
|
|
|
{'id': tag.id, 'title': get_localized_text(tag.title, language_code=lang)} |
|
|
|
|
|
for tag in obj.tags.all() |
|
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
references_block = [] |
|
|
|
|
|
reference_images_block = [] |
|
|
|
|
|
for ref in obj.references.all(): |
|
|
|
|
|
book = ref.book_reference |
|
|
|
|
|
references_block.append({ |
|
|
|
|
|
'id': ref.id, |
|
|
|
|
|
'title': get_localized_text(book.title, language_code=lang) if book else None, |
|
|
|
|
|
'authors': [ |
|
|
|
|
|
{'id': a.id, 'name': get_localized_text(a.name, language_code=lang)} |
|
|
|
|
|
for a in (book.authors.all() if book else []) |
|
|
|
|
|
], |
|
|
|
|
|
'description': book.description if book else None, |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
return Response(response_data) |
|
|
|
|
|
|
|
|
for img in ref.images.all(): |
|
|
|
|
|
reference_images_block.append({ |
|
|
|
|
|
'id': img.id, |
|
|
|
|
|
'thumbnail': f"{media_url}{img.thumbnail.url}" if img.thumbnail else None, |
|
|
|
|
|
'priority': img.priority, |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
address_details_list = [] |
|
|
|
|
|
if hasattr(obj, 'address_details') and obj.address_details and isinstance(obj.address_details, list): |
|
|
|
|
|
address_details_list = sorted(obj.address_details, key=lambda x: x.get('priority', 0)) |
|
|
|
|
|
|
|
|
|
|
|
detail_block = { |
|
|
|
|
|
'address': get_localized_text(obj.address, language_code=lang), |
|
|
|
|
|
'address_details': address_details_list, |
|
|
|
|
|
'hadis_status': status_block, |
|
|
|
|
|
'status_text': get_localized_text(obj.hadis_status_text, language_code=lang), |
|
|
|
|
|
'share_link': obj.share_link, |
|
|
|
|
|
'links': obj.links, |
|
|
|
|
|
'tags': tags_block, |
|
|
|
|
|
'references': references_block, |
|
|
|
|
|
'reference_images': reference_images_block, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# --- Narrators Block --- |
|
|
|
|
|
transmitters_data = [] |
|
|
|
|
|
for tr_rel in obj.transmitters.all(): |
|
|
|
|
|
t = tr_rel.transmitter |
|
|
|
|
|
layer = tr_rel.narrator_layer |
|
|
|
|
|
|
|
|
|
|
|
rel_data = None |
|
|
|
|
|
if t.reliability: |
|
|
|
|
|
rel_data = { |
|
|
|
|
|
'id': t.reliability.id, |
|
|
|
|
|
'title': get_localized_text(t.reliability.title, language_code=lang), |
|
|
|
|
|
'color': t.reliability.color, |
|
|
|
|
|
'main_color_code': t.reliability.main_color_code, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
transmitters_data.append({ |
|
|
|
|
|
'id': t.id, |
|
|
|
|
|
'name': get_localized_text(t.full_name, language_code=lang), |
|
|
|
|
|
'slug': t.slug, |
|
|
|
|
|
'known_as': get_localized_text(t.known_as, language_code=lang), |
|
|
|
|
|
'nickname': get_localized_text(t.nickname, language_code=lang), |
|
|
|
|
|
'reliability': rel_data, |
|
|
|
|
|
'layer_level': layer.number if layer else None, |
|
|
|
|
|
'layer_name': get_localized_text(layer.name, language_code=lang) if layer else None, |
|
|
|
|
|
'is_gap': tr_rel.is_gap, |
|
|
|
|
|
'birth_year_hijri': t.birth_year_hijri, |
|
|
|
|
|
'death_year_hijri': t.death_year_hijri, |
|
|
|
|
|
'order': tr_rel.order, |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
narrators_block = { |
|
|
|
|
|
'description': get_localized_text(obj.description, language_code=lang), |
|
|
|
|
|
'transmitters': transmitters_data, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# --- Explanations (Complex Logic) --- |
|
|
|
|
|
explanation_data = [] |
|
|
|
|
|
if hasattr(obj, 'explanations') and obj.explanations and isinstance(obj.explanations, list): |
|
|
|
|
|
for item in obj.explanations: |
|
|
|
|
|
if isinstance(item, dict) and item.get('language_code') == lang: |
|
|
|
|
|
explanation_data.append({ |
|
|
|
|
|
'title': item.get('title', ''), |
|
|
|
|
|
'description': item.get('description', '') |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
if not explanation_data and obj.explanation: |
|
|
|
|
|
explanation_data = get_localized_text(obj.explanation, language_code=lang) |
|
|
|
|
|
else: |
|
|
|
|
|
explanation_data = explanation_data if explanation_data else None |
|
|
|
|
|
|
|
|
|
|
|
# --- Corrections --- |
|
|
|
|
|
corrections_block = [] |
|
|
|
|
|
for c in obj.hadiscorrection_set.all(): |
|
|
|
|
|
corrections_block.append({ |
|
|
|
|
|
'id': c.id, |
|
|
|
|
|
'title': get_localized_text(c.title, language_code=lang), |
|
|
|
|
|
'description': get_localized_text(c.description, language_code=lang), |
|
|
|
|
|
'translation': get_localized_text(c.translation, language_code=lang), |
|
|
|
|
|
'share_link': c.share_link, |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
# --- Assemble Hadis Item --- |
|
|
|
|
|
results.append({ |
|
|
|
|
|
'id': obj.id, |
|
|
|
|
|
'number': obj.number, |
|
|
|
|
|
'slug': obj.slug, |
|
|
|
|
|
'category_id': obj.category_id, |
|
|
|
|
|
'title': get_localized_text(obj.title, language_code=lang), |
|
|
|
|
|
'title_narrator': get_localized_text(obj.title_narrator, language_code=lang), |
|
|
|
|
|
'text': obj.text, # Usually JSON structure in our app |
|
|
|
|
|
'translation': get_localized_text(obj.translation, language_code=lang), |
|
|
|
|
|
'detail': detail_block, |
|
|
|
|
|
'narrators': narrators_block, |
|
|
|
|
|
'explanations': explanation_data, |
|
|
|
|
|
'corrections': corrections_block, |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
return Response({ |
|
|
|
|
|
'count': len(results), |
|
|
|
|
|
'results': results |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HadisListView(ListAPIView): |
|
|
class HadisListView(ListAPIView): |
|
|
|