@ -690,11 +690,13 @@ class CategoryHadisCorrectionsView(ListAPIView):
@swagger_auto_schema (
operation_summary = " Get Category Hadis Corrections " ,
operation_description = " Returns all text corrections across all hadiths belonging to a specific category, including hadis_info for each correction. " ,
operation_description = " Returns all text corrections across all hadiths belonging to a specific category, including hadis_info for each correction. Supports filtering by multiple hadiths and/or categories. " ,
tags = [ ' Dobodbi - Hadis (V2) ' ] ,
manual_parameters = [
openapi . Parameter ( ' search ' , openapi . IN_QUERY , description = " Search in text or narrator " , type = openapi . TYPE_STRING ) ,
openapi . Parameter ( ' hadis_slug ' , openapi . IN_QUERY , description = " Filter corrections by specific hadith slug " , type = openapi . TYPE_STRING ) ,
openapi . Parameter ( ' hadis_slug ' , openapi . IN_QUERY , description = " Filter corrections by specific hadith slug (comma-separated for multiple) " , type = openapi . TYPE_STRING ) ,
openapi . Parameter ( ' hadis_slugs ' , openapi . IN_QUERY , description = " Filter corrections by multiple hadith slugs (comma-separated) " , type = openapi . TYPE_STRING ) ,
openapi . Parameter ( ' category_slugs ' , openapi . IN_QUERY , description = " Filter corrections by multiple category slugs (comma-separated) " , type = openapi . TYPE_STRING ) ,
openapi . Parameter ( ' is_bookmark ' , openapi . IN_QUERY , description = " Filter only bookmarked corrections (requires auth) " , type = openapi . TYPE_BOOLEAN ) ,
]
)
@ -704,12 +706,52 @@ class CategoryHadisCorrectionsView(ListAPIView):
def get_queryset ( self ) :
category_slug = self . kwargs . get ( ' category_slug ' )
try :
category_ids = [ ]
if category_slug :
category = HadisCategory . objects . get ( slug = category_slug )
category_ids = category . get_descendants ( include_self = True ) . values_list ( ' id ' , flat = True )
hadis_ids = Hadis . objects . filter (
category_id__in = category_ids ,
status = True
) . values_list ( ' id ' , flat = True )
category_ids = list ( category . get_descendants ( include_self = True ) . values_list ( ' id ' , flat = True ) )
# Optional filter by multiple categories (selected subcategories or category slugs/IDs)
cat_param_keys = [ ' category_slugs ' , ' categories ' , ' category_slug ' ]
cat_slug_list = [ ]
for key in cat_param_keys :
vals = self . request . query_params . getlist ( key ) if hasattr ( self . request . query_params , ' getlist ' ) else [ ]
if not vals and key in self . request . query_params :
val = self . request . query_params . get ( key )
if val :
vals = [ val ] if isinstance ( val , str ) else list ( val )
for v in vals :
if isinstance ( v , str ) :
cat_slug_list . extend ( [ s . strip ( ) for s in v . split ( ' , ' ) if s . strip ( ) ] )
elif isinstance ( v , ( list , tuple ) ) :
cat_slug_list . extend ( v )
elif v is not None :
cat_slug_list . append ( str ( v ) )
if cat_slug_list :
cat_filter = Q ( slug__in = cat_slug_list )
id_list = [ int ( s ) for s in cat_slug_list if str ( s ) . isdigit ( ) ]
if id_list :
cat_filter | = Q ( id__in = id_list )
selected_categories = HadisCategory . objects . filter ( cat_filter )
selected_cat_ids = set ( )
for sc in selected_categories :
selected_cat_ids . update ( sc . get_descendants ( include_self = True ) . values_list ( ' id ' , flat = True ) )
if selected_cat_ids :
if category_ids :
category_ids = list ( set ( category_ids ) . intersection ( selected_cat_ids ) )
else :
category_ids = list ( selected_cat_ids )
else :
return HadisCorrection . objects . none ( )
hadis_filter_kwargs = { ' status ' : True }
if category_ids :
hadis_filter_kwargs [ ' category_id__in ' ] = category_ids
hadis_ids = Hadis . objects . filter ( * * hadis_filter_kwargs ) . values_list ( ' id ' , flat = True )
queryset = HadisCorrection . objects . filter (
hadis_id__in = hadis_ids
@ -731,10 +773,30 @@ class CategoryHadisCorrectionsView(ListAPIView):
)
queryset = queryset . filter ( search_conditions )
# Optional filter by specific hadith slug within this category
hadis_slug = self . request . query_params . get ( ' hadis_slug ' , None )
if hadis_slug :
queryset = queryset . filter ( hadis__slug = hadis_slug )
# Optional filter by specific hadith slug(s) or ID(s)
hadis_param_keys = [ ' hadis_slug ' , ' hadis_slugs ' , ' hadiths ' ]
hadis_slug_list = [ ]
for key in hadis_param_keys :
vals = self . request . query_params . getlist ( key ) if hasattr ( self . request . query_params , ' getlist ' ) else [ ]
if not vals and key in self . request . query_params :
val = self . request . query_params . get ( key )
if val :
vals = [ val ] if isinstance ( val , str ) else list ( val )
for v in vals :
if isinstance ( v , str ) :
hadis_slug_list . extend ( [ s . strip ( ) for s in v . split ( ' , ' ) if s . strip ( ) ] )
elif isinstance ( v , ( list , tuple ) ) :
hadis_slug_list . extend ( v )
elif v is not None :
hadis_slug_list . append ( str ( v ) )
if hadis_slug_list :
hadis_query = Q ( hadis__slug__in = hadis_slug_list )
id_list = [ int ( s ) for s in hadis_slug_list if str ( s ) . isdigit ( ) ]
if id_list :
hadis_query | = Q ( hadis__id__in = id_list )
queryset = queryset . filter ( hadis_query )
# Filter by bookmarks if provided
is_bookmark = self . request . query_params . get ( ' is_bookmark ' , ' ' ) . lower ( )
@ -754,15 +816,44 @@ class CategoryHadisCorrectionsView(ListAPIView):
def list ( self , request , * args , * * kwargs ) :
response = super ( ) . list ( request , * args , * * kwargs )
category_slug = self . kwargs . get ( ' category_slug ' )
category_obj = HadisCategory . objects . filter ( slug = category_slug ) . first ( )
category_obj = HadisCategory . objects . filter ( slug = category_slug ) . first ( ) if category_slug else None
category_data = SimpleCategory ( category_obj , context = { ' request ' : request } ) . data if category_obj else None
available_hadiths = [ ]
available_categories = [ ]
if category_obj :
cat_ids = category_obj . get_descendants ( include_self = True ) . values_list ( ' id ' , flat = True )
hadiths_in_cat = Hadis . objects . filter (
category_id__in = cat_ids ,
status = True
) . order_by ( ' number ' , ' id ' )
for h in hadiths_in_cat :
h_title = get_localized_text ( h . title , request ) if hasattr ( h , ' title ' ) and h . title else f " Hadith {h.number} "
available_hadiths . append ( {
" id " : h . id ,
" number " : h . number ,
" slug " : h . slug ,
" title " : h_title ,
} )
subcats = category_obj . get_children ( ) if hasattr ( category_obj , ' get_children ' ) else category_obj . children . all ( )
for sc in subcats :
sc_title = get_localized_text ( sc . title , request ) if hasattr ( sc , ' title ' ) and sc . title else sc . slug
available_categories . append ( {
" id " : sc . id ,
" slug " : sc . slug ,
" title " : sc_title ,
} )
if isinstance ( response . data , dict ) :
ordered_data = {
' count ' : response . data . get ( ' count ' , 0 ) ,
' next ' : response . data . get ( ' next ' ) ,
' previous ' : response . data . get ( ' previous ' ) ,
' current_category ' : category_data ,
' available_hadiths ' : available_hadiths ,
' available_categories ' : available_categories ,
' results ' : response . data . get ( ' results ' , [ ] ) ,
}
response . data = ordered_data