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