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.
 
 

252 lines
9.7 KiB

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
class LocalizedField(serializers.Field):
"""
Automatically extracts the correct language from a JSON list
based on the request's ?lang= parameter.
"""
def to_representation(self, value):
# 'value' is the raw JSON list from the database
if not value or not isinstance(value, list):
return None
# Get language from request query params (default to 'fa' or 'en')
request = self.context.get('request')
target_lang = request.query_params.get('lang', 'fa') if request else 'fa'
# Logic to find the text
for item in value:
if item.get('language_code') == target_lang:
return item.get('text') # Assuming your key is 'text'
# Fallback to English
for item in value:
if item.get('language_code') == 'en':
return item.get('text')
# Fallback to first item
return value[0].get('text') if value else None
class HadisCategorySectListSerializer(serializers.ModelSerializer):
"""Serializer for HadisSect list with grouped response"""
source_types = serializers.SerializerMethodField()
title = LocalizedField()
class Meta:
model = HadisSect
fields = ['id', 'title', '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).distinct()
return list(source_types)
class HadisCategoryTreeSerializer(serializers.ModelSerializer):
title = LocalizedField()
"""Serializer for HadisCategory tree structure"""
sect_id = serializers.IntegerField(source='sect.id', read_only=True)
sect_type = serializers.CharField(source='sect.sect_type', read_only=True)
children = serializers.SerializerMethodField()
class Meta:
model = HadisCategory
fields = ['id', 'title', 'source_type', 'sect_id', 'sect_type', 'children']
def get_name(self, obj):
"""Get category name based on request language"""
request = self.context.get('request')
language_code = getattr(request, 'LANGUAGE_CODE', 'en')
return obj.get_translation(language_code) if hasattr(obj, 'get_translation') else obj.title
def get_children(self, obj):
"""Get all active children categories (no filtering by hadis/children)"""
children = obj.get_children().filter(sect=obj.sect).order_by('order')
return [self.to_dict(cat) for cat in children]
def get_hadis_count(self, obj):
"""Get total hadis count including children categories"""
# Get direct hadis count
direct_count = Hadis.objects.filter(category=obj, status=True).count()
# Get hadis count from all descendants
descendants = obj.get_descendants().filter(sect=obj.sect)
descendant_count = 0
for descendant in descendants:
descendant_count += Hadis.objects.filter(category=descendant, status=True).count()
return direct_count + descendant_count
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_xmind_file(self, obj):
"""Get absolute URL for xmind file"""
if obj.xmind_file:
request = self.context.get('request')
if request:
return request.build_absolute_uri(obj.xmind_file.url)
return obj.xmind_file.url
return None
def get_has_xmind_file(self, obj):
"""Check if category has xmind file"""
return bool(obj.xmind_file)
def get_thumbnail(self, obj):
"""Get absolute URL for thumbnail"""
if hasattr(obj, 'thumbnail') and obj.thumbnail:
request = self.context.get('request')
if request:
return request.build_absolute_uri(obj.thumbnail.url)
return obj.thumbnail.url
return None
def get_hadis_index(self, obj):
"""Get list of hadis numbers in this category (not including children)"""
return list(
Hadis.objects.filter(
category=obj,
status=True
).order_by('number').values_list('number', flat=True)
)
def to_dict(self, c):
"""Convert category to dictionary"""
children = c.get_children().filter(sect=c.sect).order_by('order')
return {
'id': c.id,
'name': self.get_name(c),
'description': c.description,
'source_type': c.source_type,
'hadis_count': self.get_hadis_count(c),
'has_hadis': self.get_has_hadis(c),
'order': c.order,
'thumbnail': self.get_thumbnail(c),
'xmind_file': self.get_xmind_file(c),
'has_xmind_file': self.get_has_xmind_file(c),
'children_count': 0 if not children else len([self.to_dict(i) for i in children]),
'children': [] if not children else [self.to_dict(i) for i in children],
}
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()
class Meta:
model = HadisCategory
fields = ['id', 'title', 'source_type','slug', 'sect_id',
'sect_type','children_count','has_hadis','hadis_count']
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)
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()
class Meta:
model = HadisCategory
fields = ['id', 'title', 'source_type','slug', 'sect_id',
'sect_type','children_count','has_hadis','hadis_count']
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 , source_type= obj.source_type)
return len(children)
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']
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)
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)