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.
 
 

240 lines
9.1 KiB

from django.utils.translation import get_language
from rest_framework import serializers
from django.utils.translation import gettext_lazy as _
# from django.db.models import Count
from ..models import HadisSect, HadisCategory, Hadis , HadisCategory
from django.utils.translation import get_language
def get_localized_text(json_list, request=None, fallback_lang="en", language_code=None):
"""
Extract localized text from a JSON list based on language.
Expects: [{"language_code": "en", "text": "..."}, ...]
Returns: Single text string or None
"""
if not json_list or not isinstance(json_list, list):
return None
# Get target language if not provided
if not language_code:
language_code = getattr(request, "LANGUAGE_CODE", None) if request else None
if not language_code:
language_code = get_language() or fallback_lang
# 1) Exact match
for item in json_list:
if isinstance(item, dict) and item.get("language_code") == language_code:
return item.get("text")
# 2) Fallback to English
for item in json_list:
if isinstance(item, dict) and item.get("language_code") == "en":
return item.get("text")
# 3) First available
if json_list and isinstance(json_list[0], dict):
return json_list[0].get("text")
return None
class LocalizedField(serializers.Field):
"""
Extracts the correct language from a JSON list
based on request.LANGUAGE_CODE (LocaleMiddleware),
with sensible fallbacks.
"""
def to_representation(self, value):
# Expecting value to be a list of {"language_code": "...", "text": "..."}
if not value or not isinstance(value, list):
return None
# Get language from request, then fall back to global language / 'fa'
request = self.context.get("request")
language_code = getattr(request, "LANGUAGE_CODE", None) if request else None
if not language_code:
language_code = get_language() or "fa" # global active language [web:164][web:172]
# 1) Exact match with request language
for item in value:
if item.get("language_code") == language_code:
return item.get("text")
# 2) Fallback to English
for item in value:
if item.get("language_code") == "en":
return item.get("text")
# 3) Fallback to first item
first = value[0]
return first.get("text") if isinstance(first, dict) else None
class SimpleCategory(serializers.ModelSerializer):
title = LocalizedField()
description = LocalizedField()
class Meta:
model = HadisCategory
fields = ['id', 'title','description']
class HadisCategorySectListSerializer(serializers.ModelSerializer):
"""Serializer for HadisSect list with grouped response"""
source_types = serializers.SerializerMethodField()
title = LocalizedField()
class Meta:
model = HadisSect
fields = ['id','sect_type', 'title','order', 'description', 'source_types']
def get_source_types(self, obj):
"""Get unique source types for this sect's categories"""
source_types = HadisCategory.objects.filter(
sect=obj
).values_list('source_type', flat=True)
# Use set to ensure uniqueness, then convert back to list
return list(set(source_types))
class HadisCategoryTreeSerializer(serializers.ModelSerializer):
title = LocalizedField()
class Meta:
model = HadisCategory
fields = ['id', 'title', 'source_type']
class HadisCategorySelectSerializer(serializers.ModelSerializer):
"""Serializer for HadisCategory Selection Flow"""
sect_id = serializers.IntegerField(source='sect.id', read_only=True)
sect_type = serializers.CharField(source='sect.sect_type', read_only=True)
# children = serializers.SerializerMethodField()
children_count = serializers.SerializerMethodField()
has_hadis = serializers.SerializerMethodField()
hadis_count= serializers.SerializerMethodField()
title = LocalizedField()
description =LocalizedField()
class Meta:
model = HadisCategory
fields = ['id', 'title', 'source_type','slug', 'sect_id',
'sect_type','description','children_count','has_hadis','hadis_count', 'share_link', 'xmind_share_link']
def get_has_hadis(self, obj):
"""Check if category can have hadis (no active children) and has hadis"""
# Check if category has active children
has_active_children = obj.get_children().filter(sect=obj.sect).exists()
# If has active children, cannot have hadis
if has_active_children:
return False
# If no active children, check if has hadis
return Hadis.objects.filter(category=obj, status=True).exists()
def get_children_count(self, obj):
# """Get count of active children categories that have children or hadis"""
# children = obj.get_children().filter(sect=obj.sect)
# return len(children)
"""
Calculates the total number of Hadiths in this category
and all its descendants (sub-categories).
"""
# 1. Get all descendants of this category (including itself)
family_tree = obj.get_descendants(include_self=True)
# 2. Count all Hadiths that belong to any category in this tree
return Hadis.objects.filter(category__in=family_tree).count()
def get_hadis_count(self,obj):
return len(Hadis.objects.filter(category=obj))
class HadisCategorySelectSourceSerializer(serializers.ModelSerializer):
"""Serializer for HadisCategory Selection Flow"""
sect_id = serializers.IntegerField(source='sect.id', read_only=True)
sect_type = serializers.CharField(source='sect.sect_type', read_only=True)
children_count = serializers.SerializerMethodField()
has_hadis = serializers.SerializerMethodField()
hadis_count = serializers.SerializerMethodField()
title = LocalizedField()
description = LocalizedField()
class Meta:
model = HadisCategory
fields = ['id', 'title', 'source_type','slug', 'sect_id',
'sect_type','description','children_count','has_hadis','hadis_count', 'share_link', 'xmind_share_link']
def get_has_hadis(self, obj):
"""Check if category can have hadis (no active children) and has hadis"""
# Check if category has active children
has_active_children = obj.get_children().filter(sect=obj.sect).exists()
# If has active children, cannot have hadis
if has_active_children:
return False
# If no active children, check if has hadis
return Hadis.objects.filter(category=obj, status=True).exists()
def get_children_count(self, obj):
# """Get count of active children categories that have children or hadis"""
# children = obj.get_children().filter(sect=obj.sect)
# return len(children)
"""
Calculates the total number of Hadiths in this category
and all its descendants (sub-categories).
"""
# 1. Get all descendants of this category (including itself)
family_tree = obj.get_descendants(include_self=True)
# 2. Count all Hadiths that belong to any category in this tree
return Hadis.objects.filter(category__in=family_tree).count()
def get_hadis_count(self,obj):
return len(Hadis.objects.filter(category=obj))
class CategorySerializer(serializers.ModelSerializer):
sect_id = serializers.IntegerField(source='sect.id', read_only=True)
sect_type = serializers.CharField(source='sect.sect_type', read_only=True)
children_count = serializers.SerializerMethodField()
has_hadis =serializers.SerializerMethodField()
hadis_count=serializers.SerializerMethodField()
title = LocalizedField()
description = LocalizedField()
class Meta:
model = HadisCategory
fields = ['id', 'title', 'sect_id', 'sect_type','source_type',
'description','slug',
'children_count','has_hadis','hadis_count', 'share_link', 'xmind_share_link']
def get_children_count(self, obj):
# """Get count of active children categories that have children or hadis"""
# children = obj.get_children().filter(sect=obj.sect)
# return len(children)
"""
Calculates the total number of Hadiths in this category
and all its descendants (sub-categories).
"""
# 1. Get all descendants of this category (including itself)
family_tree = obj.get_descendants(include_self=True)
# 2. Count all Hadiths that belong to any category in this tree
return Hadis.objects.filter(category__in=family_tree).count()
def get_has_hadis(self,obj):
return Hadis.objects.filter(category=obj).exists()
def get_hadis_count(self,obj):
return len(Hadis.objects.filter(category=obj))
# def get_title(self,obj):
# # ✅ Get language from request
# request = self.context.get('request')
# lang = request.query_params.get('lang', 'ru') if request else 'ru'
# # ✅ CALL THE MODEL METHOD!
# return obj.get_title(lang)