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.
 
 

329 lines
12 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
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 and source_type
Returns all categories in a tree structure
"""
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
).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
}
# گروه‌بندی categories بر اساس source_type
if category.source_type not in grouped_data[sect_type]['categories']:
grouped_data[sect_type]['categories'][category.source_type] = []
category_data = self.build_enhanced_category_tree(category, serializer_instance)
grouped_data[sect_type]['categories'][category.source_type].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 source_categories in sect_type_data['categories'].values():
for item in source_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 and hadis details"""
from ..models import Hadis
# 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
}
# If this child has no children but has hadis, add hadis details
if not child_data.get('children', []) and child_data.get('has_hadis', False):
try:
# Get the category object
from ..models import HadisCategory
child_category = HadisCategory.objects.get(id=child_data['id'])
# Get hadis for this category
hadis_list = Hadis.objects.filter(
category=child_category,
status=True
).order_by('number')
hadis_details = []
for hadis in hadis_list:
hadis_detail = {
'id': hadis.id,
'title': hadis.title,
'title_narrator': hadis.title_narrator,
'text': hadis.text,
'translation': hadis.get_translation(
self.request.LANGUAGE_CODE if hasattr(self, 'request') and self.request else 'en'
),
'share_link': hadis.share_link
}
hadis_details.append(hadis_detail)
child_data['hadis_details'] = hadis_details
except Exception as e:
# If there's any error, just continue without hadis details
pass
# 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 = HadisCategorySelectSerializer
@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)