@ -218,6 +218,42 @@ class Hadis(LowercaseSlugMixin, models.Model):
raise ValidationError (
raise ValidationError (
_ ( ' Cannot assign hadith to a category that has subcategories. Only leaf categories can contain hadiths. ' )
_ ( ' Cannot assign hadith to a category that has subcategories. Only leaf categories can contain hadiths. ' )
)
)
def auto_populate_title_narrator ( self ) :
"""
Auto - fills self . title_narrator if empty :
- For hadith ( or items with transmitters ) : use the ' known_as ' ( fallback ' full_name ' ) of the first narrator in the chain .
- For others ( or non - hadith / quote / quran / fatwa / history ) : use the ' known_as ' ( fallback ' name ' ) of the reference book ' s author.
"""
if self . title_narrator and isinstance ( self . title_narrator , list ) :
has_val = any (
isinstance ( item , dict ) and item . get ( ' text ' , ' ' ) . strip ( )
for item in self . title_narrator
)
if has_val :
return False
# 1. Check first transmitter in chain
if self . pk :
first_trans_rel = self . transmitters . filter ( transmitter__isnull = False ) . order_by ( ' order ' , ' id ' ) . first ( )
if first_trans_rel and first_trans_rel . transmitter :
tr = first_trans_rel . transmitter
val = tr . known_as if ( tr . known_as and isinstance ( tr . known_as , list ) and any ( isinstance ( x , dict ) and x . get ( ' text ' , ' ' ) . strip ( ) for x in tr . known_as ) ) else tr . full_name
if val and isinstance ( val , list ) :
self . title_narrator = val
return True
# 2. Check book reference author
if self . pk :
ref = self . references . filter ( book_reference__isnull = False , book_reference__author__isnull = False ) . first ( )
if ref and ref . book_reference and ref . book_reference . author :
author = ref . book_reference . author
val = author . known_as if ( author . known_as and isinstance ( author . known_as , list ) and any ( isinstance ( x , dict ) and x . get ( ' text ' , ' ' ) . strip ( ) for x in author . known_as ) ) else author . name
if val and isinstance ( val , list ) :
self . title_narrator = val
return True
return False
def save ( self , * args , * * kwargs ) :
def save ( self , * args , * * kwargs ) :
self . clean ( )
self . clean ( )
@ -249,6 +285,10 @@ class Hadis(LowercaseSlugMixin, models.Model):
old_instance . translation != self . translation ) :
old_instance . translation != self . translation ) :
self . embedded_in = [ ] # Reset!
self . embedded_in = [ ] # Reset!
# Auto-fill title_narrator if empty
if not self . title_narrator or ( isinstance ( self . title_narrator , list ) and not any ( isinstance ( item , dict ) and item . get ( ' text ' , ' ' ) . strip ( ) for item in self . title_narrator ) ) :
self . auto_populate_title_narrator ( )
# Populate normalized_text for fast and accurate Arabic/Persian search
# Populate normalized_text for fast and accurate Arabic/Persian search
from utils.text_normalizer import build_search_blob
from utils.text_normalizer import build_search_blob
self . normalized_text = build_search_blob (
self . normalized_text = build_search_blob (