You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
868 lines
32 KiB
868 lines
32 KiB
from rest_framework import serializers
|
|
from django.utils.translation import gettext_lazy as _
|
|
from rest_framework.fields import SerializerMethodField
|
|
from urllib3 import request
|
|
from .category import LocalizedField
|
|
from .category import get_localized_text
|
|
from .category import get_localized_text
|
|
from apps.bookmark.serializers.bookmark import BookmarkStatusSerializer
|
|
|
|
from ..models import (
|
|
Hadis, HadisStatus, HadisTag, HadisTransmitter,
|
|
HadisReference, ReferenceImage, Transmitters, HadisCollection,
|
|
TransmitterOpinion, TransmitterOriginalText, BookReference, BookReferenceImage, BookAuthor, HadisCorrection
|
|
)
|
|
|
|
|
|
class PinnedHadisCollectionSerializer(serializers.ModelSerializer):
|
|
title = LocalizedField()
|
|
summary = LocalizedField()
|
|
thumbnail = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = HadisCollection
|
|
# فیلدهایی که برای نمایش در بخش پین شده (مثل اسلایدر یا لیست بالا) نیاز هست
|
|
fields = ['id', 'title', 'slug', 'summary', 'thumbnail', 'order', 'created_at']
|
|
|
|
def get_thumbnail(self, obj):
|
|
if obj.thumbnail:
|
|
request = self.context.get('request')
|
|
if request:
|
|
return request.build_absolute_uri(obj.thumbnail.url)
|
|
return obj.thumbnail.url
|
|
return None
|
|
|
|
class HadisCollectionListSerializer(serializers.ModelSerializer):
|
|
thumbnail = serializers.SerializerMethodField()
|
|
title = LocalizedField()
|
|
summary = LocalizedField()
|
|
|
|
class Meta:
|
|
model = HadisCollection
|
|
fields = ['id', 'title', 'summary','slug', 'thumbnail']
|
|
|
|
def get_thumbnail(self, obj):
|
|
if obj.thumbnail:
|
|
request = self.context.get('request')
|
|
if request:
|
|
return request.build_absolute_uri(obj.thumbnail.url)
|
|
return obj.thumbnail.url
|
|
return None
|
|
|
|
|
|
class HadisSyncSerializer(serializers.ModelSerializer):
|
|
"""Serializer for syncing all hadis data (grouped fields)"""
|
|
|
|
detail = serializers.SerializerMethodField()
|
|
narrators = serializers.SerializerMethodField()
|
|
explanations = serializers.SerializerMethodField()
|
|
corrections = serializers.SerializerMethodField()
|
|
title =LocalizedField()
|
|
title_narrator = LocalizedField()
|
|
translation = LocalizedField()
|
|
|
|
class Meta:
|
|
model = Hadis
|
|
fields = [
|
|
# header (no-extend)
|
|
'id', 'number', 'slug', 'category_id', 'title', 'title_narrator', 'text', 'translation',
|
|
# grouped sections
|
|
'detail', 'narrators', 'explanations', 'corrections',
|
|
]
|
|
|
|
def get_detail(self, obj):
|
|
request = self.context.get('request')
|
|
|
|
# status
|
|
status_block = None
|
|
if obj.hadis_status:
|
|
status_block = {
|
|
'id': obj.hadis_status.id,
|
|
'title': get_localized_text(obj.hadis_status.title, request),
|
|
'color': obj.hadis_status.color,
|
|
'main_color_code': obj.hadis_status.main_color_code,
|
|
}
|
|
|
|
# tags (already prefetched)
|
|
tags_block = [
|
|
{'id': tag.id, 'title': get_localized_text(tag.title, request)}
|
|
for tag in obj.tags.all()
|
|
]
|
|
|
|
# references and reference images (already prefetched)
|
|
references_block = []
|
|
reference_images_block = []
|
|
|
|
for reference in obj.references.all():
|
|
book = reference.book_reference
|
|
authors = book.authors.all() if book else []
|
|
references_block.append({
|
|
'id': reference.id,
|
|
'title': get_localized_text(book.title, request) if book else None,
|
|
'authors': [
|
|
{'id': a.id, 'name': get_localized_text(a.name, request)}
|
|
for a in authors
|
|
],
|
|
'description': book.description if book else None,
|
|
'share_link': book.share_link if book else None,
|
|
})
|
|
|
|
for img in reference.images.all():
|
|
thumb_url = None
|
|
if img.thumbnail:
|
|
thumb_url = request.build_absolute_uri(img.thumbnail.url) if request else img.thumbnail.url
|
|
reference_images_block.append({
|
|
'id': img.id,
|
|
'thumbnail': thumb_url,
|
|
'priority': img.priority,
|
|
})
|
|
|
|
# Process address_details
|
|
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)
|
|
)
|
|
|
|
return {
|
|
'address': get_localized_text(obj.address, request),
|
|
'address_details': address_details_list,
|
|
'hadis_status': status_block,
|
|
'status_text': get_localized_text(obj.hadis_status_text, request),
|
|
'share_link': obj.share_link,
|
|
'links': obj.links,
|
|
'tags': tags_block,
|
|
'references': references_block,
|
|
'reference_images': reference_images_block,
|
|
}
|
|
|
|
|
|
def get_narrators(self, obj):
|
|
request = self.context.get('request')
|
|
|
|
transmitters_data = []
|
|
for transmitter_rel in obj.transmitters.all():
|
|
t = transmitter_rel.transmitter
|
|
layer = transmitter_rel.narrator_layer
|
|
|
|
reliability_block = None
|
|
if t.reliability:
|
|
reliability_block = {
|
|
'id': t.reliability.id,
|
|
'title': get_localized_text(t.reliability.title, request),
|
|
'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, request),
|
|
'slug': t.slug,
|
|
'known_as': get_localized_text(t.known_as, request),
|
|
'nickname': get_localized_text(t.nickname, request),
|
|
'reliability': reliability_block,
|
|
'layer_level': layer.number if layer else None,
|
|
'layer_name': get_localized_text(layer.name, request) if layer else None,
|
|
'is_gap': transmitter_rel.is_gap,
|
|
'birth_year_hijri': t.birth_year_hijri,
|
|
'death_year_hijri': t.death_year_hijri,
|
|
'order': transmitter_rel.order,
|
|
})
|
|
|
|
return {
|
|
'description': get_localized_text(obj.description, request),
|
|
'transmitters': transmitters_data,
|
|
}
|
|
|
|
|
|
def get_explanations(self, obj):
|
|
request = self.context.get('request')
|
|
# Return structured explanations with title and description
|
|
explanations_list = []
|
|
if hasattr(obj, 'explanations') and obj.explanations and isinstance(obj.explanations, list):
|
|
for item in obj.explanations:
|
|
if isinstance(item, dict):
|
|
lang = item.get('language_code')
|
|
# Check if matches request language
|
|
request_lang = request.query_params.get('lang', 'en') if request else 'en'
|
|
if lang == request_lang:
|
|
explanations_list.append({
|
|
'title': item.get('title', ''),
|
|
'description': item.get('description', '')
|
|
})
|
|
|
|
# If no match, return first available or fallback to old explanation field
|
|
if not explanations_list and obj.explanation:
|
|
return get_localized_text(obj.explanation, request)
|
|
|
|
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_text(correction.description, request),
|
|
'translation': get_localized_text(correction.translation, request),
|
|
'share_link': correction.share_link,
|
|
})
|
|
return corrections_data
|
|
|
|
class HadisListSerializer(serializers.ModelSerializer):
|
|
"""Serializer for Hadis list"""
|
|
category = serializers.SerializerMethodField()
|
|
status = serializers.SerializerMethodField()
|
|
bookmark = serializers.SerializerMethodField()
|
|
translation = LocalizedField()
|
|
title = LocalizedField()
|
|
title_narrator = LocalizedField()
|
|
|
|
class Meta:
|
|
model = Hadis
|
|
fields = ['id', 'number', 'slug', 'title', 'title_narrator', 'text',
|
|
'translation', 'category', 'status', 'bookmark', 'share_link']
|
|
|
|
def get_category(self, obj):
|
|
"""Get category id and title"""
|
|
if not obj.category:
|
|
return None
|
|
|
|
request = self.context.get('request')
|
|
|
|
# Use your helper method
|
|
title = get_localized_text(obj.category.title, request) or ""
|
|
|
|
# Safe access for sect_type to prevent crashes if sect is missing
|
|
# Note: Ensure your view uses .select_related('category__sect') for speed!
|
|
sect_type = obj.category.sect.sect_type if obj.category.sect else None
|
|
|
|
return {
|
|
'id': obj.category.id,
|
|
'title': title,
|
|
'slug': obj.category.slug,
|
|
'source_type': obj.category.source_type,
|
|
'sect_type': sect_type
|
|
}
|
|
|
|
def get_status(self, obj):
|
|
"""Get status id and title"""
|
|
if not obj.hadis_status:
|
|
return None
|
|
|
|
request = self.context.get('request')
|
|
|
|
# Use your helper method
|
|
title = get_localized_text(obj.hadis_status.title, request)
|
|
|
|
return {
|
|
'id': obj.hadis_status.id,
|
|
'title': title,
|
|
'color': obj.hadis_status.color,
|
|
'main_color_code': obj.hadis_status.main_color_code,
|
|
}
|
|
|
|
def get_bookmark(self, obj):
|
|
"""Get bookmark information for this playlist."""
|
|
request = self.context.get('request')
|
|
user = request.user if request else None
|
|
book_mark = BookmarkStatusSerializer.get_bookmark_info(
|
|
obj=obj,
|
|
user=user,
|
|
service='hadith'
|
|
)
|
|
return book_mark.get('is_bookmarked', False)
|
|
|
|
class HadisStatusSerializer(serializers.ModelSerializer):
|
|
"""Serializer for HadisStatus"""
|
|
title = LocalizedField()
|
|
description = LocalizedField()
|
|
main_color_code = serializers.ReadOnlyField()
|
|
class Meta:
|
|
model = HadisStatus
|
|
fields = ['id', 'title', 'color', 'main_color_code', 'description']
|
|
|
|
|
|
class HadisTagSerializer(serializers.ModelSerializer):
|
|
"""Serializer for HadisTag"""
|
|
title = LocalizedField()
|
|
|
|
class Meta:
|
|
model = HadisTag
|
|
fields = ['id', 'title']
|
|
|
|
|
|
class TransmitterSerializer(serializers.ModelSerializer):
|
|
"""Serializer for Transmitters"""
|
|
full_name = LocalizedField()
|
|
known_as = LocalizedField()
|
|
nickname = LocalizedField()
|
|
reliability = serializers.SerializerMethodField()
|
|
share_link = serializers.CharField(read_only=True)
|
|
|
|
class Meta:
|
|
model = Transmitters
|
|
fields = [
|
|
'id', 'full_name', 'slug','birth_year_hijri', 'death_year_hijri',
|
|
"known_as",'nickname','reliability','madhhab','generation','share_link'
|
|
]
|
|
|
|
def get_reliability(self, obj):
|
|
"""Serialize the reliability foreign key"""
|
|
if obj.reliability:
|
|
return {
|
|
'id': obj.reliability.id,
|
|
'title': get_localized_text(obj.reliability.title, self.context.get('request')),
|
|
'color': obj.reliability.color,
|
|
'main_color_code': obj.reliability.main_color_code,
|
|
}
|
|
return None
|
|
|
|
class TransmitterShortSerializer(serializers.ModelSerializer):
|
|
"""Serializer for Transmitters"""
|
|
full_name = LocalizedField()
|
|
known_as = LocalizedField()
|
|
nickname = LocalizedField()
|
|
|
|
class Meta:
|
|
model = Transmitters
|
|
fields = [
|
|
'id', 'full_name', 'slug','birth_year_hijri', 'death_year_hijri',
|
|
"known_as",'nickname','reliability'
|
|
]
|
|
class TransmitterOpinionSerializer(serializers.ModelSerializer):
|
|
""" Serializer for TransmitterOpinions """
|
|
scholar_name = LocalizedField()
|
|
opinion_text = LocalizedField()
|
|
status = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = TransmitterOpinion
|
|
fields = ['id','transmitter','scholar_name','opinion_text','status']
|
|
|
|
def get_status(self, obj):
|
|
"""Serialize the opinion status foreign key"""
|
|
if obj.status:
|
|
request = self.context.get('request')
|
|
return {
|
|
'id': obj.status.id,
|
|
'title': get_localized_text(obj.status.title, request),
|
|
'slug': obj.status.slug,
|
|
'color': obj.status.color,
|
|
'main_color_code': obj.status.main_color_code,
|
|
}
|
|
return None
|
|
|
|
class TransmitterOriginalTextSerializer(serializers.ModelSerializer):
|
|
""" Serializer for TransmitterOriginalText """
|
|
title = LocalizedField()
|
|
text = LocalizedField()
|
|
translation =LocalizedField()
|
|
|
|
class Meta:
|
|
model = TransmitterOriginalText
|
|
fields = ['id', 'title', 'text', 'translation', 'share_link']
|
|
|
|
|
|
class TransmitterDetailSerializer(serializers.ModelSerializer):
|
|
""" Serializer for Details of Transmitters """
|
|
|
|
full_name = LocalizedField()
|
|
known_as = LocalizedField()
|
|
nickname = LocalizedField()
|
|
kunya = LocalizedField()
|
|
origin = LocalizedField()
|
|
lived_in = LocalizedField()
|
|
died_in = LocalizedField()
|
|
description = LocalizedField()
|
|
reliability = serializers.SerializerMethodField()
|
|
share_link = serializers.CharField(read_only=True)
|
|
|
|
class Meta:
|
|
model = Transmitters
|
|
fields = [
|
|
'id','full_name','kunya','known_as','nickname',
|
|
'origin','lived_in','died_in','birth_year_hijri',
|
|
'death_year_hijri','age_at_death','reliability',
|
|
'madhhab',"in_sahih_muslim","in_sahih_bukhari",
|
|
"description",'generation','share_link'
|
|
]
|
|
|
|
def get_reliability(self, obj):
|
|
"""Serialize the reliability foreign key"""
|
|
if obj.reliability:
|
|
return {
|
|
'id': obj.reliability.id,
|
|
'title': get_localized_text(obj.reliability.title, self.context.get('request')),
|
|
'color': obj.reliability.color,
|
|
'main_color_code': obj.reliability.main_color_code,
|
|
}
|
|
return None
|
|
|
|
class TransmittersFiltersSerializer(serializers.ModelSerializer):
|
|
pass
|
|
|
|
class TransmitterSyncSerializer(serializers.ModelSerializer):
|
|
"""Serializer for syncing all transmitter data for offline mode"""
|
|
|
|
biographical = serializers.SerializerMethodField()
|
|
scholars_opinions = serializers.SerializerMethodField()
|
|
original_texts = serializers.SerializerMethodField()
|
|
full_name = LocalizedField()
|
|
|
|
class Meta:
|
|
model = Transmitters
|
|
fields = [
|
|
'id', 'full_name','slug' ,'biographical', 'scholars_opinions', 'original_texts'
|
|
]
|
|
|
|
def get_biographical(self, obj):
|
|
"""Get biographical information (flattened)"""
|
|
request = self.context.get('request') # ← FIX: Define request
|
|
if obj.reliability:
|
|
r= {
|
|
'id': obj.reliability.id,
|
|
'title': get_localized_text(obj.reliability.title, self.context.get('request')),
|
|
'color': obj.reliability.color,
|
|
'main_color_code': obj.reliability.main_color_code,
|
|
}
|
|
else :
|
|
r= None
|
|
|
|
return {
|
|
'full_name': get_localized_text(obj.full_name, request),
|
|
'kunya': get_localized_text(obj.kunya, request),
|
|
'known_as': get_localized_text(obj.known_as, request),
|
|
'nickname': get_localized_text(obj.nickname, request),
|
|
'origin': get_localized_text(obj.origin, request),
|
|
'lived_in': get_localized_text(obj.lived_in, request),
|
|
'died_in': get_localized_text(obj.died_in, request),
|
|
'birth_year_hijri': obj.birth_year_hijri,
|
|
'death_year_hijri': obj.death_year_hijri,
|
|
'age_at_death': obj.age_at_death,
|
|
'generation': obj.generation,
|
|
'reliability': r,
|
|
'madhhab': obj.madhhab,
|
|
'in_sahih_muslim': obj.in_sahih_muslim,
|
|
'in_sahih_bukhari': obj.in_sahih_bukhari,
|
|
'description': get_localized_text(obj.description, request),
|
|
'thumbnail': obj.thumbnail.url if obj.thumbnail else None,
|
|
'share_link': obj.share_link,
|
|
}
|
|
|
|
def get_scholars_opinions(self, obj):
|
|
"""Get all scholarly opinions about this transmitter"""
|
|
request = self.context.get('request') # ← FIX: Define request
|
|
|
|
return [
|
|
{
|
|
'id': opinion.id,
|
|
'scholar_name': get_localized_text(opinion.scholar_name, request),
|
|
'opinion_text': get_localized_text(opinion.opinion_text, request),
|
|
'status': {
|
|
'id': opinion.status.id,
|
|
'title': get_localized_text(opinion.status.title, request),
|
|
'slug': opinion.status.slug,
|
|
'color': opinion.status.color,
|
|
'main_color_code': opinion.status.main_color_code,
|
|
} if opinion.status else None,
|
|
'created_at': opinion.created_at.isoformat() if opinion.created_at else None,
|
|
'updated_at': opinion.updated_at.isoformat() if opinion.updated_at else None,
|
|
}
|
|
for opinion in obj.opinions.all() # Already prefetched
|
|
]
|
|
|
|
def get_original_texts(self, obj):
|
|
"""Get original texts of the transmitter"""
|
|
request = self.context.get('request') # ← FIX: Define request
|
|
|
|
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
|
|
]
|
|
|
|
|
|
|
|
class HadisTransmitterSerializer(serializers.ModelSerializer):
|
|
|
|
"""Serializer for HadisTransmitter with transmitter details"""
|
|
transmitter = TransmitterShortSerializer(read_only=True)
|
|
layer = serializers.SerializerMethodField()
|
|
status = serializers.SerializerMethodField()
|
|
class Meta:
|
|
model = HadisTransmitter
|
|
fields = [
|
|
'id', 'order', 'is_gap','layer', 'transmitter', 'status'
|
|
]
|
|
|
|
|
|
|
|
def get_layer(self, obj):
|
|
"""Get narrator layer slug"""
|
|
return obj.narrator_layer.slug if obj.narrator_layer else None
|
|
|
|
def get_status(self, obj):
|
|
"""Serialize the status foreign key"""
|
|
if obj.status:
|
|
request = self.context.get('request')
|
|
return {
|
|
'id': obj.status.id,
|
|
'title': get_localized_text(obj.status.title, request),
|
|
'slug': obj.status.slug,
|
|
'color': obj.status.color,
|
|
'main_color_code': obj.status.main_color_code,
|
|
}
|
|
return None
|
|
|
|
# serializers.py
|
|
|
|
class HadisTransmitterListSerializer(serializers.ModelSerializer):
|
|
"""
|
|
The 'Parent' Serializer.
|
|
It takes a HADIS object and returns the count + the list of transmitters.
|
|
"""
|
|
layer_count = serializers.SerializerMethodField()
|
|
layer_names = serializers.SerializerMethodField()
|
|
results = HadisTransmitterSerializer(
|
|
source='transmitters', # Access the 'transmitters' reverse relation
|
|
many=True,
|
|
read_only=True
|
|
)
|
|
|
|
class Meta:
|
|
model = Hadis
|
|
fields = ['id', 'layer_count','layer_names', 'results']
|
|
|
|
def get_layer_count(self, obj):
|
|
# Calculate distinct layers efficiently
|
|
return obj.transmitters.values('narrator_layer').distinct().count()
|
|
def get_layer_names(self, obj):
|
|
"""Get list of localized narrator layer names"""
|
|
request = self.context.get('request')
|
|
|
|
# Import here to get actual objects
|
|
from apps.hadis.models import NarratorLayer
|
|
|
|
# Get ALL distinct narrator layer IDs for this hadis (not filtered)
|
|
# This ensures layer names are returned regardless of layer filtering
|
|
all_layers_for_hadis = HadisTransmitter.objects.filter(
|
|
hadis=obj
|
|
).values_list('narrator_layer', flat=True).distinct()
|
|
|
|
layer_objects = NarratorLayer.objects.filter(id__in=all_layers_for_hadis)
|
|
|
|
# Extract localized names
|
|
layer_names = []
|
|
for layer in layer_objects:
|
|
name =get_localized_text(layer.name, request=request)
|
|
description = get_localized_text(layer.description, request=request)
|
|
slug = layer.slug
|
|
layer_names.append({
|
|
'name': name,
|
|
'slug': slug,
|
|
'description': description
|
|
})
|
|
|
|
return layer_names
|
|
|
|
class ReferenceImageSerializer(serializers.ModelSerializer):
|
|
"""Serializer for ReferenceImage"""
|
|
thumbnail = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = ReferenceImage
|
|
fields = ['id', 'thumbnail', 'priority']
|
|
|
|
def get_thumbnail(self, obj):
|
|
"""Get thumbnail URL"""
|
|
if obj.thumbnail:
|
|
request = self.context.get('request')
|
|
if request:
|
|
return request.build_absolute_uri(obj.thumbnail.url)
|
|
return obj.thumbnail.url
|
|
return None
|
|
|
|
|
|
class HadisReferenceSerializer(serializers.ModelSerializer):
|
|
"""Serializer for HadisReference with book and images"""
|
|
book_title = serializers.SerializerMethodField()
|
|
book_authors = serializers.SerializerMethodField()
|
|
book_description = serializers.SerializerMethodField()
|
|
share_link = serializers.CharField(source='book_reference.share_link', read_only=True)
|
|
class Meta:
|
|
model = HadisReference
|
|
fields = [
|
|
'id', 'book_title', 'book_description','book_authors','share_link'
|
|
]
|
|
|
|
# def get_type_name(self, obj):
|
|
# """Get localized type name from book_reference.type"""
|
|
# if obj.book_reference and obj.book_reference.type:
|
|
# field = LocalizedField()
|
|
# field._context = self.context
|
|
# return field.to_representation(obj.book_reference.type.title)
|
|
# return None
|
|
|
|
# def get_subject_area(self, obj):
|
|
# """Get list of localized subject area names"""
|
|
# if obj.book_reference and obj.book_reference.subject_area.exists():
|
|
# subject_areas = []
|
|
# field = LocalizedField()
|
|
# field._context = self.context
|
|
|
|
# for subject in obj.book_reference.subject_area.all():
|
|
# subject_areas.append(field.to_representation(subject.title))
|
|
|
|
# return subject_areas
|
|
# return []
|
|
|
|
# def get_book_english_name(self,obj):
|
|
# english_name_data = obj.book_reference.title
|
|
# for item in english_name_data:
|
|
# if item.get('language_code') == 'en':
|
|
# return item.get('text')
|
|
# return None
|
|
|
|
# def get_book_language(self,obj):
|
|
# language_data = obj.book_reference.language
|
|
# field = LocalizedField()
|
|
# field._context = self.context
|
|
|
|
# return field.to_representation(language_data)
|
|
|
|
def get_book_title(self, obj):
|
|
title_data = obj.book_reference.title
|
|
field = LocalizedField()
|
|
field._context = self.context
|
|
|
|
return field.to_representation(title_data)
|
|
|
|
def get_book_authors(self, obj):
|
|
"""Get list of localized author names"""
|
|
try:
|
|
# 1. Fetch the BookAuthor objects
|
|
authors = obj.book_reference.authors.all()
|
|
|
|
if not authors:
|
|
return []
|
|
|
|
# 2. Prepare your localized field helper
|
|
field = LocalizedField()
|
|
field._context = self.context
|
|
|
|
# 3. Loop through authors and convert each object to a string (name)
|
|
# Result will be like: ["Al-Bukhari", "Muslim"]
|
|
out = []
|
|
for author in authors:
|
|
name = field.to_representation(author.name)
|
|
|
|
# Format birth and death dates (Hijri/CE)
|
|
birth_hijri = author.birth_year_hijri
|
|
birth_miladi = author.birth_year_miladi
|
|
death_hijri = author.death_year_hijri
|
|
death_miladi = author.death_year_miladi
|
|
|
|
birth_str = ""
|
|
if birth_hijri and birth_miladi:
|
|
birth_str = f"{birth_hijri}AH/{birth_miladi}CE"
|
|
elif birth_hijri:
|
|
birth_str = f"{birth_hijri}AH"
|
|
elif birth_miladi:
|
|
birth_str = f"{birth_miladi}CE"
|
|
|
|
death_str = ""
|
|
if death_hijri and death_miladi:
|
|
death_str = f"{death_hijri}AH/{death_miladi}CE"
|
|
elif death_hijri:
|
|
death_str = f"{death_hijri}AH"
|
|
elif death_miladi:
|
|
death_str = f"{death_miladi}CE"
|
|
|
|
out.append({
|
|
'name': name,
|
|
'birth': birth_str,
|
|
'death': death_str,
|
|
})
|
|
|
|
return out
|
|
|
|
except Exception:
|
|
return []
|
|
def get_book_description(self, obj):
|
|
description_data = obj.book_reference.description
|
|
field = LocalizedField()
|
|
field._context = self.context
|
|
|
|
return field.to_representation(description_data)
|
|
|
|
class HadisCorrectionSerializer(serializers.ModelSerializer):
|
|
"""Serializer for HadisCorrection"""
|
|
title = LocalizedField()
|
|
description = LocalizedField()
|
|
translation = LocalizedField()
|
|
bookmark = serializers.SerializerMethodField()
|
|
class Meta:
|
|
model = HadisCorrection
|
|
fields = ['id', 'title','slug', 'description', 'translation','share_link','bookmark']
|
|
|
|
def get_bookmark(self, obj):
|
|
"""Get bookmark information for this correction."""
|
|
request = self.context.get('request')
|
|
user = request.user if request else None
|
|
book_mark = BookmarkStatusSerializer.get_bookmark_info(
|
|
obj=obj,
|
|
user=user,
|
|
service='hadith_correction'
|
|
)
|
|
return book_mark.get('is_bookmarked', False)
|
|
|
|
|
|
class HadisBasicSerializer(serializers.ModelSerializer):
|
|
"""Basic serializer for Hadis with minimal information"""
|
|
translation = LocalizedField()
|
|
category = serializers.SerializerMethodField()
|
|
bookmark= serializers.SerializerMethodField()
|
|
|
|
title = LocalizedField()
|
|
title_narrator = LocalizedField()
|
|
explanation = LocalizedField()
|
|
# explanations = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Hadis
|
|
fields = [
|
|
'id', 'slug', 'title','bookmark', 'title_narrator', 'text',
|
|
'translation', 'share_link','explanation','category'
|
|
]
|
|
|
|
# def get_explanations(self, obj):
|
|
# """Get structured explanations for the requested language"""
|
|
# request = self.context.get('request')
|
|
# request_lang = request.query_params.get('lang', 'en') if request else 'en'
|
|
|
|
# explanations_list = []
|
|
# if obj.explanations and isinstance(obj.explanations, list):
|
|
# for item in obj.explanations:
|
|
# if isinstance(item, dict) and item.get('language_code') == request_lang:
|
|
# explanations_list.append({
|
|
# 'title': item.get('title', ''),
|
|
# 'description': item.get('description', '')
|
|
# })
|
|
|
|
# return explanations_list if explanations_list else None
|
|
|
|
|
|
def get_category(self, obj):
|
|
"""Get category id and title"""
|
|
if obj.category:
|
|
request = self.context.get('request')
|
|
|
|
return {
|
|
'id': obj.category.id,
|
|
'title': get_localized_text(obj.title,request),
|
|
'slug':obj.category.slug,
|
|
'source_type':obj.category.source_type,
|
|
'sect_type':obj.category.sect.sect_type
|
|
}
|
|
return None
|
|
def get_bookmark(self, obj):
|
|
"""Get bookmark information for this playlist."""
|
|
request = self.context.get('request')
|
|
user = request.user if request else None
|
|
book_mark = BookmarkStatusSerializer.get_bookmark_info(
|
|
obj=obj,
|
|
user=user,
|
|
service='hadith'
|
|
)
|
|
return book_mark.get('is_bookmarked', False)
|
|
|
|
|
|
class HadisShortSerializer(serializers.ModelSerializer):
|
|
"""Basic serializer for Hadis with minimal information"""
|
|
translation = LocalizedField()
|
|
|
|
title = LocalizedField()
|
|
title_narrator = LocalizedField()
|
|
|
|
class Meta:
|
|
model = Hadis
|
|
fields = [
|
|
'id', 'slug', 'title', 'title_narrator', 'text',
|
|
'translation', 'share_link']
|
|
|
|
|
|
|
|
class HadisDetailSerializer(serializers.ModelSerializer):
|
|
"""Detailed serializer for Hadis with core information (transmitters and corrections moved to separate endpoints)"""
|
|
hadis_status = HadisStatusSerializer(read_only=True)
|
|
tags = HadisTagSerializer(many=True, read_only=True)
|
|
references = HadisReferenceSerializer(
|
|
many=True,
|
|
read_only=True
|
|
)
|
|
reference_images = SerializerMethodField()
|
|
address = LocalizedField()
|
|
# address_details = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Hadis
|
|
fields = [
|
|
'id', 'number', 'slug','hadis_status','links','share_link',
|
|
'tags','references','reference_images','address'
|
|
]
|
|
|
|
# def get_address_details(self, obj):
|
|
# """Get address details sorted by priority"""
|
|
# if obj.address_details and isinstance(obj.address_details, list):
|
|
# return sorted(obj.address_details, key=lambda x: x.get('priority', 0))
|
|
# return []
|
|
|
|
def get_reference_images(self, obj):
|
|
"""Get all reference images from all references"""
|
|
all_images = []
|
|
for reference in obj.references.all():
|
|
images = reference.images.all().order_by('priority')
|
|
serializer = ReferenceImageSerializer(images, many=True, context=self.context)
|
|
all_images.extend(serializer.data)
|
|
return all_images
|
|
|
|
# def get_category(self, obj):
|
|
# """Get category details"""
|
|
# if obj.category:
|
|
# return {
|
|
# 'id': obj.category.id,
|
|
# 'title': obj.category.title,
|
|
# 'category_type': obj.category.content_type
|
|
# }
|
|
# return None
|
|
|
|
def get_translation(self, obj):
|
|
"""Get translation based on request language"""
|
|
request = self.context.get('request')
|
|
language_code = getattr(request, 'LANGUAGE_CODE', 'en')
|
|
return obj.translation.get(language_code)
|
|
|
|
|
|
class NarratorLayerSerializer(serializers.Serializer):
|
|
"""Serializer for narrator layers information"""
|
|
name = serializers.SerializerMethodField()
|
|
slug = serializers.CharField(read_only=True)
|
|
description = serializers.SerializerMethodField()
|
|
|
|
def get_name(self, obj):
|
|
"""Get localized name"""
|
|
request = self.context.get('request')
|
|
return get_localized_text(obj.name, request=request)
|
|
|
|
def get_description(self, obj):
|
|
"""Get localized description"""
|
|
request = self.context.get('request')
|
|
return get_localized_text(obj.description, request=request)
|