@ -66,24 +66,58 @@ class NarratorLayer(models.Model):
return None
def save ( self , * args , * * kwargs ) :
if not self . slug :
if not self . slug or ( isinstance ( self . slug , str ) and self . slug . strip ( ) == ' ' ) :
# Try to get text from name field with robust error handling
try :
if self . name and isinstance ( self . name , list ) and len ( self . name ) > 0 :
text = self . name [ 0 ] . get ( ' text ' , ' ' ) . strip ( )
if text :
slug = slugify ( text )
first_item = self . name [ 0 ]
if isinstance ( first_item , dict ) :
text = first_item . get ( ' text ' , ' ' ) . strip ( )
if text :
slug = slugify ( text )
# Ensure uniqueness
counter = 1
base_slug = slug
while NarratorLayer . objects . filter ( slug = slug ) . exclude ( pk = self . pk ) . exists ( ) :
slug = f " {base_slug}-{counter} "
counter + = 1
self . slug = slug
else :
# Fallback to layer number if text is empty
base_slug = f " layer-{self.number} "
slug = base_slug
counter = 1
while NarratorLayer . objects . filter ( slug = slug ) . exclude ( pk = self . pk ) . exists ( ) :
slug = f " {base_slug}-{counter} "
counter + = 1
self . slug = slug
else :
# Fallback to layer number if text is empty
slug = f " layer-{self.number} "
# Fallback to layer number if name structure is invalid
base_slug = f " layer-{self.number} "
slug = base_slug
counter = 1
while NarratorLayer . objects . filter ( slug = slug ) . exclude ( pk = self . pk ) . exists ( ) :
slug = f " {base_slug}-{counter} "
counter + = 1
self . slug = slug
else :
# Fallback to layer number if name structure is invalid
slug = f " layer-{self.number} "
base_slug = f " layer-{self.number} "
slug = base_slug
counter = 1
while NarratorLayer . objects . filter ( slug = slug ) . exclude ( pk = self . pk ) . exists ( ) :
slug = f " {base_slug}-{counter} "
counter + = 1
self . slug = slug
except ( IndexError , KeyError , AttributeError , TypeError ) :
# Fallback to layer number on any error
slug = f " layer-{self.number} "
self . slug = slug
base_slug = f " layer-{self.number} "
slug = base_slug
counter = 1
while NarratorLayer . objects . filter ( slug = slug ) . exclude ( pk = self . pk ) . exists ( ) :
slug = f " {base_slug}-{counter} "
counter + = 1
self . slug = slug
super ( ) . save ( * args , * * kwargs )
class TransmitterReliability ( models . Model ) :
@ -102,25 +136,59 @@ class TransmitterReliability(models.Model):
color = models . CharField ( max_length = 20 , choices = ColorChoices . choices , verbose_name = _ ( ' color ' ) )
def save ( self , * args , * * kwargs ) :
if not self . slug :
if not self . slug or ( isinstance ( self . slug , str ) and self . slug . strip ( ) == ' ' ) :
# Try to get text from title field with robust error handling
try :
if self . title and isinstance ( self . title , list ) and len ( self . title ) > 0 :
text = self . title [ 0 ] . get ( ' text ' , ' ' ) . strip ( )
if text :
slug = slugify ( text )
first_item = self . title [ 0 ]
if isinstance ( first_item , dict ) :
text = first_item . get ( ' text ' , ' ' ) . strip ( )
if text :
slug = slugify ( text )
# Ensure uniqueness
counter = 1
base_slug = slug
while TransmitterReliability . objects . filter ( slug = slug ) . exclude ( pk = self . pk ) . exists ( ) :
slug = f " {base_slug}-{counter} "
counter + = 1
self . slug = slug
else :
# Fallback to a timestamp-based slug
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " reliability-{suffix} "
counter = 1
while TransmitterReliability . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " reliability-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
else :
# Fallback to a timestamp-based slug
from datetime import datetime
slug = f " reliability-{datetime.now().strftime( ' % Y % m %d % H % M % S %f ' )} "
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " reliability-{suffix} "
counter = 1
while TransmitterReliability . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " reliability-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
else :
from datetime import datetime
slug = f " reliability-{datetime.now().strftime( ' % Y % m %d % H % M % S %f ' )} "
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " reliability-{suffix} "
counter = 1
while TransmitterReliability . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " reliability-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
except ( IndexError , KeyError , AttributeError , TypeError ) :
from datetime import datetime
slug = f " reliability-{datetime.now().strftime( ' % Y % m %d % H % M % S %f ' )} "
self . slug = slug
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " reliability-{suffix} "
counter = 1
while TransmitterReliability . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " reliability-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
super ( ) . save ( * args , * * kwargs )
def __str__ ( self ) :
@ -229,15 +297,61 @@ class Transmitters(models.Model):
ordering = ( ' full_name ' , )
def save ( self , * args , * * kwargs ) :
if not self . slug :
name = self . full_name [ 0 ]
base_slug = slugify ( name . get ( ' text ' ) , allow_unicode = True )
slug = base_slug
counter = 1
while Transmitters . objects . filter ( slug = slug ) . exclude ( pk = self . pk ) . exists ( ) :
slug = f " {base_slug}-{counter} "
counter + = 1
self . slug = slug
if not self . slug or ( isinstance ( self . slug , str ) and self . slug . strip ( ) == ' ' ) :
# Try to get text from full_name field with robust error handling
try :
if self . full_name and isinstance ( self . full_name , list ) and len ( self . full_name ) > 0 :
first_item = self . full_name [ 0 ]
if isinstance ( first_item , dict ) :
name_text = first_item . get ( ' text ' , ' ' ) . strip ( )
if name_text :
base_slug = slugify ( name_text , allow_unicode = True )
slug = base_slug
counter = 1
while Transmitters . objects . filter ( slug = slug ) . exclude ( pk = self . pk ) . exists ( ) :
slug = f " {base_slug}-{counter} "
counter + = 1
self . slug = slug
else :
# Fallback if text is empty
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " transmitter-{suffix} "
counter = 1
while Transmitters . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " transmitter-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
else :
# Fallback if structure is invalid
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " transmitter-{suffix} "
counter = 1
while Transmitters . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " transmitter-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
else :
# Fallback if full_name is empty or invalid
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " transmitter-{suffix} "
counter = 1
while Transmitters . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " transmitter-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
except ( IndexError , KeyError , AttributeError , TypeError ) :
# Fallback on any error
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " transmitter-{suffix} "
counter = 1
while Transmitters . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " transmitter-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
super ( ) . save ( * args , * * kwargs )
def _get_json_field ( self , field_name : str , lang : Optional [ str ] = None , fallback : str = " en " ) :
@ -367,25 +481,59 @@ class OpinionStatus(models.Model):
color = models . CharField ( max_length = 20 , choices = ColorChoices . choices , verbose_name = _ ( ' color ' ) )
def save ( self , * args , * * kwargs ) :
if not self . slug :
if not self . slug or ( isinstance ( self . slug , str ) and self . slug . strip ( ) == ' ' ) :
# Try to get text from title field with robust error handling
try :
if self . title and isinstance ( self . title , list ) and len ( self . title ) > 0 :
text = self . title [ 0 ] . get ( ' text ' , ' ' ) . strip ( )
if text :
slug = slugify ( text )
first_item = self . title [ 0 ]
if isinstance ( first_item , dict ) :
text = first_item . get ( ' text ' , ' ' ) . strip ( )
if text :
slug = slugify ( text )
# Ensure uniqueness
counter = 1
base_slug = slug
while OpinionStatus . objects . filter ( slug = slug ) . exclude ( pk = self . pk ) . exists ( ) :
slug = f " {base_slug}-{counter} "
counter + = 1
self . slug = slug
else :
# Fallback to a timestamp-based slug
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " opinion-{suffix} "
counter = 1
while OpinionStatus . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " opinion-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
else :
# Fallback to a timestamp-based slug
from datetime import datetime
slug = f " opinion-{datetime.now().strftime( ' % Y % m %d % H % M % S %f ' )} "
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " opinion-{suffix} "
counter = 1
while OpinionStatus . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " opinion-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
else :
from datetime import datetime
slug = f " opinion-{datetime.now().strftime( ' % Y % m %d % H % M % S %f ' )} "
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " opinion-{suffix} "
counter = 1
while OpinionStatus . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " opinion-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
except ( IndexError , KeyError , AttributeError , TypeError ) :
from datetime import datetime
slug = f " opinion-{datetime.now().strftime( ' % Y % m %d % H % M % S %f ' )} "
self . slug = slug
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
base_slug = f " opinion-{suffix} "
counter = 1
while OpinionStatus . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " opinion-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
super ( ) . save ( * args , * * kwargs )
def __str__ ( self ) :
@ -536,12 +684,22 @@ class TransmitterOriginalText(models.Model):
instance = self ,
)
else :
# Fallback if title is empty
self . slug = f " original-text-{self.transmitter.slug}-{self.id or ' unknown ' } "
# Fallback if title is empty - use timestamp for uniqueness
import time
suffix = int ( time . time ( ) * 1000 ) % 1000000
transmitter_slug = self . transmitter . slug if self . transmitter and self . transmitter . slug else ' unknown '
base_slug = f " original-text-{transmitter_slug}-{suffix} "
# Ensure uniqueness
counter = 1
while TransmitterOriginalText . objects . filter ( slug = base_slug ) . exclude ( pk = self . pk ) . exists ( ) :
base_slug = f " original-text-{transmitter_slug}-{suffix}-{counter} "
counter + = 1
self . slug = base_slug
# Call parent save
if not self . share_link :
# Generate share_link before saving
if not self . share_link and self . slug and self . transmitter and self . transmitter . slug :
self . share_link = f " {settings.SITE_DOMAIN}/hadis/narrators/{self.transmitter.slug}/original-texts/{self.slug} "
super ( ) . save ( * args , * * kwargs )