Browse Source

feat(transmitters): auto-populate original text title from connected book reference

- Implement auto_populate_title on TransmitterOriginalText model using linked BookReference title
- Auto-fill title in serializer create/update and OriginalTextReference viewset
- Ensure smart slug and share_link are updated accordingly when title is auto-populated
master
Mohsen Taba 1 week ago
parent
commit
811cdbb403
  1. 26
      apps/hadis/models/transmitter.py
  2. 38
      apps/hadis/serializers/serializers_admin.py
  3. 14
      apps/hadis/views_admin.py

26
apps/hadis/models/transmitter.py

@ -1080,10 +1080,36 @@ class TransmitterOriginalText(models.Model):
title = "Untitled" title = "Untitled"
return f"{title} by {self.transmitter}" return f"{title} by {self.transmitter}"
def auto_populate_title(self):
"""
Auto-fills self.title if empty, using the title of the linked BookReference.
"""
if self.title and isinstance(self.title, list):
has_val = any(
isinstance(item, dict) and (item.get('text', '') or item.get('title', '')).strip()
for item in self.title
)
if has_val:
return False
if self.pk:
ref = self.references.filter(book_reference__isnull=False).first()
if ref and ref.book_reference and ref.book_reference.title:
b_title = ref.book_reference.title
if isinstance(b_title, list) and any(isinstance(x, dict) and (x.get('text', '') or x.get('title', '')).strip() for x in b_title):
self.title = b_title
return True
return False
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
""" """
Override save to automatically generate smart slugs. Override save to automatically generate smart slugs.
""" """
# Auto-fill title from book reference if empty
if not self.title or (isinstance(self.title, list) and not any(isinstance(item, dict) and (item.get('text', '') or item.get('title', '')).strip() for item in self.title)):
self.auto_populate_title()
from utils.slug import build_slug_for_instance from utils.slug import build_slug_for_instance
build_slug_for_instance(self, source_field='title') build_slug_for_instance(self, source_field='title')

38
apps/hadis/serializers/serializers_admin.py

@ -3598,6 +3598,20 @@ class AdminTransmitterOriginalTextSerializer(serializers.ModelSerializer):
address = validated_data.pop("address", None) address = validated_data.pop("address", None)
delete_image_ids = validated_data.pop("delete_image_ids", []) delete_image_ids = validated_data.pop("delete_image_ids", [])
# Pre-fill title from book reference if title is empty
title_val = validated_data.get("title")
has_title = isinstance(title_val, list) and any(
isinstance(item, dict) and (item.get('text', '') or item.get('title', '')).strip()
for item in title_val
)
if not has_title and book_reference_id:
try:
b_ref = BookReference.objects.filter(id=book_reference_id.id if hasattr(book_reference_id, 'id') else book_reference_id).first()
if b_ref and b_ref.title:
validated_data["title"] = b_ref.title
except Exception:
pass
instance = super().create(validated_data) instance = super().create(validated_data)
ref_data = { ref_data = {
@ -3606,6 +3620,11 @@ class AdminTransmitterOriginalTextSerializer(serializers.ModelSerializer):
"delete_image_ids": delete_image_ids, "delete_image_ids": delete_image_ids,
} }
save_relation_reference_data(instance, ref_data, request=request, ref_type="original_text") save_relation_reference_data(instance, ref_data, request=request, ref_type="original_text")
if not instance.title or (isinstance(instance.title, list) and not any(isinstance(item, dict) and (item.get('text', '') or item.get('title', '')).strip() for item in instance.title)):
if instance.auto_populate_title():
instance.save(update_fields=['title', 'slug', 'share_link'])
return instance return instance
def update(self, instance, validated_data): def update(self, instance, validated_data):
@ -3614,6 +3633,20 @@ class AdminTransmitterOriginalTextSerializer(serializers.ModelSerializer):
address = validated_data.pop("address", None) address = validated_data.pop("address", None)
delete_image_ids = validated_data.pop("delete_image_ids", []) delete_image_ids = validated_data.pop("delete_image_ids", [])
# Pre-fill title from book reference if title is empty
title_val = validated_data.get("title")
has_title = isinstance(title_val, list) and any(
isinstance(item, dict) and (item.get('text', '') or item.get('title', '')).strip()
for item in title_val
)
if not has_title and book_reference_id:
try:
b_ref = BookReference.objects.filter(id=book_reference_id.id if hasattr(book_reference_id, 'id') else book_reference_id).first()
if b_ref and b_ref.title:
validated_data["title"] = b_ref.title
except Exception:
pass
instance = super().update(instance, validated_data) instance = super().update(instance, validated_data)
ref_data = { ref_data = {
@ -3622,6 +3655,11 @@ class AdminTransmitterOriginalTextSerializer(serializers.ModelSerializer):
"delete_image_ids": delete_image_ids, "delete_image_ids": delete_image_ids,
} }
save_relation_reference_data(instance, ref_data, request=request, ref_type="original_text") save_relation_reference_data(instance, ref_data, request=request, ref_type="original_text")
if not instance.title or (isinstance(instance.title, list) and not any(isinstance(item, dict) and (item.get('text', '') or item.get('title', '')).strip() for item in instance.title)):
if instance.auto_populate_title():
instance.save(update_fields=['title', 'slug', 'share_link'])
return instance return instance

14
apps/hadis/views_admin.py

@ -1566,6 +1566,20 @@ class AdminInterpretationReferenceViewSet(ModelViewSet):
class AdminOriginalTextReferenceViewSet(ModelViewSet): class AdminOriginalTextReferenceViewSet(ModelViewSet):
def perform_create(self, serializer):
instance = serializer.save()
ot = instance.original_text
if ot and (not ot.title or (isinstance(ot.title, list) and not any(isinstance(x, dict) and (x.get('text', '') or x.get('title', '')).strip() for x in ot.title))):
if ot.auto_populate_title():
ot.save(update_fields=['title', 'slug', 'share_link'])
def perform_update(self, serializer):
instance = serializer.save()
ot = instance.original_text
if ot and (not ot.title or (isinstance(ot.title, list) and not any(isinstance(x, dict) and (x.get('text', '') or x.get('title', '')).strip() for x in ot.title))):
if ot.auto_populate_title():
ot.save(update_fields=['title', 'slug', 'share_link'])
serializer_class = AdminOriginalTextReferenceSerializer serializer_class = AdminOriginalTextReferenceSerializer
permission_classes = [IsAuthenticated, IsSuperAdmin] permission_classes = [IsAuthenticated, IsSuperAdmin]

Loading…
Cancel
Save