Browse Source

layer names fixed regerdless of filterings.

master
Mohsen Taba 4 months ago
parent
commit
c4c146eba9
  1. 129
      apps/hadis/management/commands/reformat_data.py
  2. 86
      apps/hadis/management/commands/seed_corrections.py
  3. 21
      apps/hadis/serializers/hadis.py

129
apps/hadis/management/commands/reformat_data.py

@ -0,0 +1,129 @@
import random
from django.core.management.base import BaseCommand
from django.db import transaction
# REPLACE 'apps.hadis.models' with your actual app path
from apps.hadis.models import Hadis
class Command(BaseCommand):
help = 'Updates explanation and address fields with structured multilingual dummy data'
def handle(self, *args, **options):
self.stdout.write("Starting bulk update of Explanation and Address fields...")
hadis_qs = Hadis.objects.all()
total_hadis = hadis_qs.count()
if total_hadis == 0:
self.stdout.write(self.style.WARNING("No Hadis found to update."))
return
self.stdout.write(f"Found {total_hadis} Hadis records.")
# --- DATA POOLS FOR RANDOM VARIATION ---
# 1. Address Data (Hierarchical strings: Book -> Chapter -> Section)
address_pool = [
{
"en": ["Sahih al-Bukhari", "Book of Revelation", "Chapter 1"],
"fa": ["صحیح بخاری", "کتاب وحی", "باب ۱"],
"ru": ["Сахих аль-Бухари", "Книга откровения", "Глава 1"]
},
{
"en": ["Riyad as-Salihin", "The Book of Knowledge", "Virtues of Seeking Knowledge"],
"fa": ["ریاض الصالحین", "کتاب علم", "فضیلت طلب علم"],
"ru": ["Рияд ас-Салихин", "Книга знаний", "Достоинства поиска знаний"]
},
{
"en": ["Sunan Abi Dawud", "Book of Prayer", "Details of Prostration"],
"fa": ["سنن ابی داوود", "کتاب صلاه", "جزئیات سجده"],
"ru": ["Сунан Абу Дауд", "Книга молитвы", "Детали земного поклона"]
}
]
# 2. Explanation Data (Title/Detail objects)
explanation_pool = [
{
"en": [
{"title": "Vocabulary", "detail": "The term 'Niyyah' implies the resolve of the heart."},
{"title": "Context", "detail": "Narrated by Omar bin Al-Khattab regarding migration to Medina."}
],
"fa": [
{"title": "لغات", "detail": "واژه «نیت» به معنای قصد و عزم قلبی است."},
{"title": "شأن نزول", "detail": "این حدیث از عمر بن خطاب در مورد مهاجرت به مدینه روایت شده است."}
],
"ru": [
{"title": "Словарь", "detail": "Термин «Ният» подразумевает решимость сердца."},
{"title": "Контекст", "detail": "Передано Омаром ибн аль-Хаттабом относительно переселения в Медину."}
]
},
{
"en": [
{"title": "Legal Ruling", "detail": "Scholars agree that this action is Mustahabb (recommended)."},
{"title": "Benefits", "detail": "Increases spirituality and mindfulness in daily life."}
],
"fa": [
{"title": "حکم فقهی", "detail": "علما اتفاق نظر دارند که این عمل مستحب است."},
{"title": "فواید", "detail": "باعث افزایش معنویت و توجه در زندگی روزمره می‌شود."}
],
"ru": [
{"title": "Правoвое решение", "detail": "Ученые согласны, что это действие является желательным (мустахаб)."},
{"title": "Польза", "detail": "Повышает духовность и осознанность в повседневной жизни."}
]
}
]
updated_count = 0
# Iterate and Update
for i, hadis in enumerate(hadis_qs, 1):
if i % 100 == 0:
self.stdout.write(f"Processing {i}/{total_hadis}...")
# Pick random samples to make data look diverse
addr_sample = random.choice(address_pool)
exp_sample = random.choice(explanation_pool)
# --- CONSTRUCT ADDRESS FORMAT (List of Strings) ---
# Format: [{"language_code": "en", "text": ["A", "B"]}, ...]
new_address = [
{
"language_code": "en",
"text": addr_sample["en"]
},
{
"language_code": "fa",
"text": addr_sample["fa"]
},
{
"language_code": "ru",
"text": addr_sample["ru"]
}
]
# --- CONSTRUCT EXPLANATION FORMAT (List of Objects) ---
# Format: [{"language_code": "en", "text": [{"title":.., "detail":..}]}, ...]
new_explanation = [
{
"language_code": "en",
"text": exp_sample["en"]
},
{
"language_code": "fa",
"text": exp_sample["fa"]
},
{
"language_code": "ru",
"text": exp_sample["ru"]
}
]
# Assign to fields
hadis.address = new_address
hadis.explanation = new_explanation
# Save (Using save() ensures signals/dates update, though slower than bulk_update)
# Since we modify JSON fields, simple save is safest.
hadis.save()
updated_count += 1
self.stdout.write(self.style.SUCCESS(f"Successfully updated {updated_count} Hadis records with new format."))

86
apps/hadis/management/commands/seed_corrections.py

@ -1,14 +1,13 @@
import random
from django.core.management.base import BaseCommand
from django.db import transaction
# REPLACE 'apps.hadis.models' with the actual path to your models if different
from django.db import transaction, IntegrityError
# REPLACE 'apps.hadis.models' with your actual path
from apps.hadis.models import Hadis, HadisCorrection
class Command(BaseCommand):
help = 'Seeds HadisCorrection instances to ensure every Hadis has at least 4 corrections'
help = 'Seeds HadisCorrection instances ensuring unique titles to prevent slug collisions'
def create_json_field(self, en_text, ru_text):
"""Helper to construct the multilingual JSON structure"""
return [
{"text": en_text, "language_code": "en"},
{"text": ru_text, "language_code": "ru"}
@ -17,19 +16,17 @@ class Command(BaseCommand):
def handle(self, *args, **options):
self.stdout.write("Starting HadisCorrection seeding...")
# 1. Fetch all Hadis
hadis_qs = Hadis.objects.all()
total_hadis = hadis_qs.count()
if total_hadis == 0:
self.stdout.write(self.style.WARNING("No Hadis found to correct!"))
self.stdout.write(self.style.WARNING("No Hadis found!"))
return
self.stdout.write(f"Found {total_hadis} Hadis records. Checking correction counts...")
self.stdout.write(f"Found {total_hadis} Hadis records.")
total_created = 0
# 2. Iterate and Create
for i, hadis in enumerate(hadis_qs, 1):
if i % 50 == 0:
self.stdout.write(f"Processing {i}/{total_hadis}...")
@ -41,44 +38,45 @@ class Command(BaseCommand):
if needed <= 0:
continue
with transaction.atomic():
for k in range(needed):
# Calculate a visual number for titles (e.g., Correction 1, Correction 2)
correction_num = current_count + k + 1
# We use a try-except block inside the loop to handle potential rare collisions gracefully
try:
with transaction.atomic():
for k in range(needed):
correction_num = current_count + k + 1
# --- Generate Content ---
# Titles: specific to grammar, context, or translation
topics_en = ["Grammar Correction", "Context Clarification", "Alternative Translation", "Scholar Note"]
topics_ru = ["Исправление грамматики", "Уточнение контекста", "Альтернативный перевод", "Заметка ученого"]
topic_idx = (correction_num - 1) % len(topics_en)
title_data = self.create_json_field(
f"{topics_en[topic_idx]} #{correction_num}",
f"{topics_ru[topic_idx]} #{correction_num}"
)
topics_en = ["Grammar Correction", "Context Clarification", "Alternative Translation", "Scholar Note"]
topics_ru = ["Исправление грамматики", "Уточнение контекста", "Альтернативный перевод", "Заметка ученого"]
topic_idx = (correction_num - 1) % len(topics_en)
# --- CRITICAL FIX: Add Hadis Number to Title ---
# This makes the title unique per Hadis, producing unique slugs naturally
# e.g., "Grammar Correction #1 (Hadis 2050)" -> "grammar-correction-1-hadis-2050"
title_en = f"{topics_en[topic_idx]} #{correction_num} (Hadis {hadis.number})"
title_ru = f"{topics_ru[topic_idx]} #{correction_num} (Хадис {hadis.number})"
title_data = self.create_json_field(title_en, title_ru)
desc_data = self.create_json_field(
f"This is a detailed explanation regarding the {topics_en[topic_idx].lower()} for Hadith {hadis.number}.",
f"Это подробное объяснение, касающееся {topics_ru[topic_idx].lower()} для Хадиса {hadis.number}."
)
desc_data = self.create_json_field(
f"Detailed explanation regarding the {topics_en[topic_idx].lower()} for Hadith {hadis.number}.",
f"Подробное объяснение касательно {topics_ru[topic_idx].lower()} для Хадиса {hadis.number}."
)
# Simulating a corrected translation snippet
translation_data = self.create_json_field(
f"Revised text segment for correction {correction_num}...",
f"Пересмотренный фрагмент текста для исправления {correction_num}..."
)
translation_data = self.create_json_field(
f"Revised text segment...",
f"Пересмотренный фрагмент..."
)
# --- Create Instance ---
# We use .create() so the model's .save() method is called.
# This ensures 'slug' and 'share_link' are automatically generated by your model logic.
HadisCorrection.objects.create(
hadis=hadis,
title=title_data,
description=desc_data,
translation=translation_data
)
total_created += 1
HadisCorrection.objects.create(
hadis=hadis,
title=title_data,
description=desc_data,
translation=translation_data
)
total_created += 1
except IntegrityError as e:
self.stdout.write(self.style.ERROR(f"Skipped Hadis {hadis.id} due to slug collision: {e}"))
continue
self.stdout.write(self.style.SUCCESS(f"Done! Successfully created {total_created} new HadisCorrection instances."))
self.stdout.write(self.style.SUCCESS(f"Done! Created {total_created} new corrections."))

21
apps/hadis/serializers/hadis.py

@ -510,23 +510,24 @@ class HadisTransmitterListSerializer(serializers.ModelSerializer):
def get_layer_names(self, obj):
"""Get list of localized narrator layer names"""
request = self.context.get('request')
# Get distinct narrator layer objects (not just IDs)
layers = obj.transmitters.values_list(
'narrator_layer', flat=True
).distinct()
# Import here to get actual objects
from apps.hadis.models import NarratorLayer
layer_objects = NarratorLayer.objects.filter(id__in=layers)
# Get ALL distinct narrator layer IDs for this hadis (not filtered)
# This ensures layer names are returned regardless of layer filtering
all_layers_for_hadis = HadisTransmitter.objects.filter(
hadis=obj
).values_list('narrator_layer', flat=True).distinct()
layer_objects = NarratorLayer.objects.filter(id__in=all_layers_for_hadis)
# Extract localized names
layer_names = [
get_localized_text(layer.name, request=request)
for layer in layer_objects
]
return layer_names
class ReferenceImageSerializer(serializers.ModelSerializer):

Loading…
Cancel
Save