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.
 
 

295 lines
10 KiB

from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from utils.pagination import NoPagination
from ..models import HadisSect, HadisCategory
from ..serializers import HadisCategorySectListSerializer, HadisCategoryTreeSerializer, CategorySerializer , HadisCategorySelectSerializer , HadisCategorySelectSourceSerializer
from ..docs import (
hadis_sect_list_swagger,
hadis_category_tree_swagger,
categories_list_swagger,
categories_by_sect_swagger,
categories_tree_by_sect_swagger,
categories_tree_by_sect_source_swagger
)
class HadisCategorySectListView(ListAPIView):
"""
API view to list all HadisSects grouped by sect_type (shia/sunni)
"""
queryset = HadisSect.objects.filter(is_active=True).order_by('order')
serializer_class = HadisCategorySectListSerializer
pagination_class = NoPagination
@hadis_sect_list_swagger
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
response = super().list(request, *args, **kwargs)
lang = request.LANGUAGE_CODE
# Group sects by type
grouped_data = {
'shia': [],
'sunni': []
}
for sect in queryset:
sect_data = {
'id': sect.id,
'title': sect.title,
}
if sect.sect_type == HadisSect.SectType.SHIA:
grouped_data['shia'].append(sect_data)
elif sect.sect_type == HadisSect.SectType.SUNNI:
grouped_data['sunni'].append(sect_data)
# Create response with count and results
response_data = {
'count': queryset.count(),
'results': grouped_data
}
return Response(response_data)
class HadisCategoryTreeView(ListAPIView):
"""
API view to get all HadisCategory tree structure grouped by sect
Returns all categories in a tree structure (source_type grouping removed for mobile filtering)
"""
serializer_class = HadisCategoryTreeSerializer
pagination_class = NoPagination
@hadis_category_tree_swagger
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def get_queryset(self):
return HadisCategory.objects.filter(
parent__isnull=True,
sect__is_active=True
).select_related('sect').prefetch_related(
'children',
'children__children'
).order_by('sect__order', 'order')
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
grouped_data = {}
serializer_instance = HadisCategoryTreeSerializer(context={'request': request})
# گروه‌بندی بر اساس sect_type (shia/sunni)
for category in queryset:
sect_type = category.sect.sect_type
if sect_type not in grouped_data:
# ایجاد گروه برای هر sect_type
grouped_data[sect_type] = {
'sects': {},
'categories': []
}
# اضافه کردن اطلاعات sect به گروه sect_type
sect_id = str(category.sect.id)
if sect_id not in grouped_data[sect_type]['sects']:
grouped_data[sect_type]['sects'][sect_id] = {
'id': category.sect.id,
'sect_type': category.sect.sect_type,
'title': category.sect.title,
'description': category.sect.description,
'order': category.sect.order
}
category_data = self.build_enhanced_category_tree(category, serializer_instance)
grouped_data[sect_type]['categories'].append(category_data)
def count_children(children_list):
count = 0
for item in children_list:
count += 1
if 'children' in item and item['children']:
count += count_children(item['children'])
return count
total_count = 0
for sect_type_data in grouped_data.values():
for item in sect_type_data['categories']:
total_count += 1
if 'children' in item and item['children']:
total_count += count_children(item['children'])
response_data = {
'count': total_count,
'results': grouped_data
}
return Response(response_data)
def build_enhanced_category_tree(self, category, serializer_instance):
"""Build enhanced category tree with father category info and hadis details"""
base_data = serializer_instance.to_dict(category)
# Enhance children with additional information
enhanced_children = []
for child_data in base_data.get('children', []):
enhanced_child = self.enhance_child_data(child_data, category, serializer_instance)
enhanced_children.append(enhanced_child)
base_data['children'] = enhanced_children
return base_data
def enhance_child_data(self, child_data, parent_category, serializer_instance):
"""Enhance child data with father category info (no hadis payload for sync tree)"""
# Add father category information
child_data['father_category'] = {
'id': parent_category.id,
'name': parent_category.title,
'sect_id': parent_category.sect.id,
'sect_type': parent_category.sect.sect_type,
'source_type': parent_category.source_type
}
# Note: we intentionally DO NOT load or attach hadis details here for performance.
# Recursively enhance children's children
if child_data.get('children', []):
enhanced_grandchildren = []
try:
from ..models import HadisCategory
child_category = HadisCategory.objects.get(id=child_data['id'])
for grandchild_data in child_data['children']:
enhanced_grandchild = self.enhance_child_data(grandchild_data, child_category, serializer_instance)
enhanced_grandchildren.append(enhanced_grandchild)
except:
# If there's an error, keep original children
enhanced_grandchildren = child_data['children']
child_data['children'] = enhanced_grandchildren
return child_data
class HadisCategoryTreeNormalView(ListAPIView):
"""
Normal (paginated) tree view for HadisCategory.
Unlike the sync view, this simply returns the root categories (filtered to active sects)
with their nested children, and uses the project's default pagination.
"""
serializer_class = HadisCategoryTreeSerializer
@hadis_category_tree_swagger
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def get_queryset(self):
return HadisCategory.objects.filter(
parent__isnull=True,
sect__is_active=True
).order_by('sect__order', 'order')
class HadisCategorySelectBySectView(ListAPIView):
"""
Tree view for HadisCategory filtered by sect_type and category slug.
Returns the children categories of the specified category (by slug) within the sect_type.
"""
serializer_class = HadisCategorySelectSerializer
@categories_tree_by_sect_swagger
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def get_queryset(self):
sect_type = self.kwargs.get('sect_type')
slug = self.kwargs.get('slug')
# Find the parent category by slug and sect_type
try:
parent_category = HadisCategory.objects.get(
slug=slug,
sect__sect_type=sect_type,
sect__is_active=True
)
except HadisCategory.DoesNotExist:
return HadisCategory.objects.none()
# Return children of this category, filtered as before
return HadisCategory.objects.filter(
parent=parent_category,
sect__sect_type=sect_type,
sect__is_active=True
).order_by('order')
class HadisCategorySelectBySectSourceView(ListAPIView):
"""
Tree view for HadisCategory filtered by sect_type, category slug and source_type.
Returns the children categories of the specified category (by slug) within the sect_type, filtered by source_type.
"""
serializer_class = HadisCategorySelectSourceSerializer
@categories_tree_by_sect_source_swagger
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def get_queryset(self):
sect_type = self.kwargs.get('sect_type')
slug = self.kwargs.get('slug')
source_type = self.kwargs.get('source_type')
# Find the parent category by slug and sect_type
try:
parent_category = HadisCategory.objects.get(
slug=slug,
sect__sect_type=sect_type,
sect__is_active=True
)
except HadisCategory.DoesNotExist:
return HadisCategory.objects.none()
# Return children of this category, filtered by source_type
return HadisCategory.objects.filter(
parent=parent_category,
sect__sect_type=sect_type,
sect__is_active=True,
source_type=source_type
).order_by('order')
class CategoriesView(ListAPIView):
"""
API view to list all HadisCategories
"""
queryset = HadisCategory.objects.all()
serializer_class = CategorySerializer
@categories_list_swagger
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
class CategoriesBySectView(ListAPIView):
"""
API view to list HadisCategories filtered by sect_type
"""
serializer_class = CategorySerializer
def get_queryset(self):
sect_type = self.kwargs.get('sect_type')
return HadisCategory.objects.filter(sect__sect_type=sect_type)
@categories_by_sect_swagger
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)