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
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)
|
|
|
|
|