3 changed files with 90 additions and 250 deletions
-
323apps/hadis/management/commands/seed_transmitters.py
-
4apps/hadis/models/transmitter.py
-
1apps/hadis/serializers/hadis.py
@ -1,270 +1,109 @@ |
|||||
import random |
import random |
||||
from django.core.management.base import BaseCommand |
from django.core.management.base import BaseCommand |
||||
from django.core.exceptions import ObjectDoesNotExist |
|
||||
# Ensure these imports match your actual app structure |
|
||||
from apps.hadis.models import ( |
|
||||
NarratorLayer, |
|
||||
Transmitters, |
|
||||
HadisTransmitter, |
|
||||
TransmitterOpinion, |
|
||||
TransmitterOriginalText, |
|
||||
Hadis, |
|
||||
TransmitterReliability |
|
||||
) |
|
||||
|
from django.db import transaction |
||||
|
# REPLACE 'apps.hadis.models' WITH YOUR ACTUAL APP PATH |
||||
|
from apps.hadis.models import Transmitters, TransmitterOpinion, TransmitterOriginalText, OpinionStatus |
||||
|
|
||||
class Command(BaseCommand): |
class Command(BaseCommand): |
||||
help = 'Seeds the database with mock Transmitters, Layers, and Chains' |
|
||||
|
|
||||
def create_json_field(self, en_text, fa_text, ru_text): |
|
||||
"""Helper to create your specific JSON format with Russian added""" |
|
||||
return [ |
|
||||
{"text": en_text, "language_code": "en"}, |
|
||||
{"text": fa_text, "language_code": "fa"}, |
|
||||
{"text": ru_text, "language_code": "ru"} |
|
||||
] |
|
||||
|
help = 'Seeds TransmitterOpinion and TransmitterOriginalText for transmitters 84-91' |
||||
|
|
||||
def handle(self, *args, **options): |
def handle(self, *args, **options): |
||||
self.stdout.write("--- Starting Transmitters Mock Data Generation (Trilingual) ---") |
|
||||
|
self.stdout.write("Starting Transmitter Details seeding...") |
||||
|
|
||||
# --------------------------------------------------------- |
# --------------------------------------------------------- |
||||
# 1. Create Narrator Layers (Tabaqat) |
|
||||
|
# 1. Fetch Target Objects |
||||
# --------------------------------------------------------- |
# --------------------------------------------------------- |
||||
self.stdout.write("Creating Narrator Layers...") |
|
||||
layers_data = [ |
|
||||
(1, "Companions", "صحابه", "Сподвижники", |
|
||||
"Companions of the Prophet", "یاران پیامبر", "Сподвижники Пророка"), |
|
||||
(2, "Successors", "تابعین", "Табиины", |
|
||||
"The generation after Companions", "نسل بعد از صحابه", "Поколение после сподвижников"), |
|
||||
(3, "Successors of Successors", "تابع تابعین", "Таби ат-Табиин", |
|
||||
"The third generation", "نسل سوم", "Третье поколение передатчиков"), |
|
||||
(4, "Students of the Imams", "شاگردان ائمه", "Ученики Имамов", |
|
||||
"Direct students of the Imams", "شاگردان مستقیم ائمه", "Прямые ученики Имамов"), |
|
||||
(5, "Minor Narrators", "راویان جزئی", "Малые передатчики", |
|
||||
"Lesser known narrators", "راویان کمتر شناخته شده", "Малоизвестные передатчики"), |
|
||||
] |
|
||||
|
transmitters = Transmitters.objects.filter(id__range=(84, 91)) |
||||
|
|
||||
created_layers = [] |
|
||||
for num, en, fa, ru, en_d, fa_d, ru_d in layers_data: |
|
||||
layer, created = NarratorLayer.objects.get_or_create( |
|
||||
number=num, |
|
||||
defaults={ |
|
||||
'name': self.create_json_field(en, fa, ru), |
|
||||
'description': self.create_json_field(en_d, fa_d, ru_d) |
|
||||
} |
|
||||
) |
|
||||
created_layers.append(layer) |
|
||||
self.stdout.write(self.style.SUCCESS(f"Verified {len(created_layers)} layers.")) |
|
||||
|
if not transmitters.exists(): |
||||
|
self.stdout.write(self.style.ERROR("No Transmitters found in range 84-91.")) |
||||
|
return |
||||
|
|
||||
# --------------------------------------------------------- |
|
||||
# 2. Create Transmitters |
|
||||
# --------------------------------------------------------- |
|
||||
self.stdout.write("Creating Transmitters...") |
|
||||
|
# Fetch OpinionStatus objects |
||||
|
# We need these to populate the 'status' ForeignKey in TransmitterOpinion |
||||
|
statuses = list(OpinionStatus.objects.all()) |
||||
|
|
||||
transmitters_list = [ |
|
||||
{ |
|
||||
"full_name": ("Zurarah bin Ayan", "زرارة بن اعین", "Зурара ибн Аян"), |
|
||||
"kunya": ("Abu Ali", "ابو علی", "Абу Али"), |
|
||||
"origin": ("Kufa", "کوفه", "Куфа"), |
|
||||
"reliability": Transmitters.ReliabilityLevel.VERY_RELIABLE, |
|
||||
"madhhab": Transmitters.MadhhabChoices.SHIA, |
|
||||
"died": 150, |
|
||||
"layer": 4 |
|
||||
}, |
|
||||
{ |
|
||||
"full_name": ("Muhammad bin Muslim", "محمد بن مسلم", "Мухаммад ибн Муслим"), |
|
||||
"kunya": ("Abu Ja'far", "ابو جعفر", "Абу Джафар"), |
|
||||
"origin": ("Kufa", "کوفه", "Куфа"), |
|
||||
"reliability": Transmitters.ReliabilityLevel.VERY_RELIABLE, |
|
||||
"madhhab": Transmitters.MadhhabChoices.SHIA, |
|
||||
"died": 150, |
|
||||
"layer": 4 |
|
||||
}, |
|
||||
{ |
|
||||
"full_name": ("Abu Basir Al-Asadi", "ابو بصیر الاسدی", "Абу Басир Аль-Асади"), |
|
||||
"kunya": ("Abu Muhammad", "ابو محمد", "Абу Мухаммад"), |
|
||||
"origin": ("Kufa", "کوفه", "Куфа"), |
|
||||
"reliability": Transmitters.ReliabilityLevel.RELIABLE, |
|
||||
"madhhab": Transmitters.MadhhabChoices.SHIA, |
|
||||
"died": 150, |
|
||||
"layer": 4 |
|
||||
}, |
|
||||
{ |
|
||||
"full_name": ("Yunus bin Abd al-Rahman", "یونس بن عبدالرحمن", "Юнус ибн Абд ар-Рахман"), |
|
||||
"kunya": ("Abu Muhammad", "ابو محمد", "Абу Мухаммад"), |
|
||||
"origin": ("Baghdad", "بغداد", "Багдад"), |
|
||||
"reliability": Transmitters.ReliabilityLevel.VERY_RELIABLE, |
|
||||
"madhhab": Transmitters.MadhhabChoices.SHIA, |
|
||||
"died": 208, |
|
||||
"layer": 3 |
|
||||
}, |
|
||||
{ |
|
||||
"full_name": ("Hammad bin Isa", "حماد بن عیسی", "Хаммад ибн Иса"), |
|
||||
"kunya": ("Abu Amin", "ابو امین", "Абу Амин"), |
|
||||
"origin": ("Basra", "بصره", "Басра"), |
|
||||
"reliability": Transmitters.ReliabilityLevel.RELIABLE, |
|
||||
"madhhab": Transmitters.MadhhabChoices.SHIA, |
|
||||
"died": 209, |
|
||||
"layer": 3 |
|
||||
}, |
|
||||
{ |
|
||||
"full_name": ("Ibrahim bin Hashim", "ابراهیم بن هاشم", "Ибрагим ибн Хашим"), |
|
||||
"kunya": ("Abu Ishaq", "ابو اسحاق", "Абу Исхак"), |
|
||||
"origin": ("Qom", "قم", "Кум"), |
|
||||
"reliability": Transmitters.ReliabilityLevel.ACCEPTABLE, |
|
||||
"madhhab": Transmitters.MadhhabChoices.SHIA, |
|
||||
"died": 250, |
|
||||
"layer": 2 |
|
||||
}, |
|
||||
{ |
|
||||
"full_name": ("Sahl bin Ziyad", "سهل بن زیاد", "Сахль ибн Зияд"), |
|
||||
"kunya": ("Abu Sa'id", "ابو سعید", "Абу Саид"), |
|
||||
"origin": ("Rayy", "ری", "Рей"), |
|
||||
"reliability": Transmitters.ReliabilityLevel.WEAK, |
|
||||
"madhhab": Transmitters.MadhhabChoices.SHIA, |
|
||||
"died": 255, |
|
||||
"layer": 2 |
|
||||
}, |
|
||||
{ |
|
||||
"full_name": ("Jabir bin Hayyan", "جابر بن حیان", "Джабир ибн Хайян"), |
|
||||
"kunya": ("Abu Musa", "ابو موسی", "Абу Муса"), |
|
||||
"origin": ("Tus", "توس", "Тус"), |
|
||||
"reliability": Transmitters.ReliabilityLevel.UNKNOWN, |
|
||||
"madhhab": Transmitters.MadhhabChoices.OTHER, |
|
||||
"died": 195, |
|
||||
"layer": 3 |
|
||||
}, |
|
||||
] |
|
||||
|
# Fallback: If no statuses exist, we can't create opinions safely without knowing your Status model fields. |
||||
|
if not statuses: |
||||
|
self.stdout.write(self.style.ERROR("No 'OpinionStatus' objects found! Please create some via Admin first.")) |
||||
|
return |
||||
|
|
||||
created_transmitters = [] |
|
||||
|
|
||||
for t_data in transmitters_list: |
|
||||
# Check if exists by simple slug check (EN name) |
|
||||
en_name = t_data["full_name"][0] |
|
||||
# Replace spaces with dash for rough slug matching |
|
||||
slug_guess = en_name.lower().replace(' ', '-') |
|
||||
|
|
||||
existing = Transmitters.objects.filter(slug__startswith=slug_guess) |
|
||||
|
|
||||
if existing.exists(): |
|
||||
self.stdout.write(f"Skipping {en_name}, likely exists.") |
|
||||
created_transmitters.append(existing.first()) |
|
||||
continue |
|
||||
|
|
||||
transmitter = Transmitters( |
|
||||
full_name=self.create_json_field(*t_data["full_name"]), |
|
||||
kunya=self.create_json_field(*t_data["kunya"]), |
|
||||
origin=self.create_json_field(*t_data["origin"]), |
|
||||
lived_in=self.create_json_field(*t_data["origin"]), |
|
||||
died_in=self.create_json_field("Unknown", "نامشخص", "Неизвестно"), |
|
||||
reliability=t_data["reliability"], |
|
||||
madhhab=t_data["madhhab"], |
|
||||
death_year_hijri=t_data["died"], |
|
||||
description=self.create_json_field( |
|
||||
f"A narrator from {t_data['origin'][0]}", |
|
||||
f"راوی اهل {t_data['origin'][1]}", |
|
||||
f"Передатчик из города {t_data['origin'][2]}" |
|
||||
) |
|
||||
) |
|
||||
transmitter.save() |
|
||||
created_transmitters.append(transmitter) |
|
||||
self.stdout.write(self.style.SUCCESS(f"Created transmitter: {en_name}")) |
|
||||
|
self.stdout.write(f"Found {transmitters.count()} Transmitters and {len(statuses)} Opinion Statuses.") |
||||
|
|
||||
# --------------------------------------------------------- |
# --------------------------------------------------------- |
||||
# 3. Create Opinions |
|
||||
|
# 2. Data Generators (Helpers) |
||||
# --------------------------------------------------------- |
# --------------------------------------------------------- |
||||
self.stdout.write("Adding Opinions...") |
|
||||
if created_transmitters: |
|
||||
t_target = created_transmitters[0] # Zurarah |
|
||||
TransmitterOpinion.objects.create( |
|
||||
transmitter=t_target, |
|
||||
scholar_name=self.create_json_field("Al-Najashi", "النجاشی", "Аль-Наджаши"), |
|
||||
opinion_text=self.create_json_field( |
|
||||
"He is the master of our companions and their teacher.", |
|
||||
"او بزرگ اصحاب ما و استاد آنان است.", |
|
||||
"Он — господин наших сподвижников и их учитель." |
|
||||
), |
|
||||
status=TransmitterOpinion.OpinionStatus.CONFIRMED |
|
||||
) |
|
||||
|
scholars = [ |
||||
|
{"en": "Al-Dhahabi", "ar": "الذهبي", "fa": "ذهبی"}, |
||||
|
{"en": "Ibn Hajar", "ar": "ابن حجر", "fa": "ابن حجر"}, |
||||
|
{"en": "Al-Tusi", "ar": "الطوسي", "fa": "طوسی"}, |
||||
|
{"en": "Al-Najashi", "ar": "النجاشي", "fa": "نجاشی"}, |
||||
|
] |
||||
|
|
||||
t_weak = next((t for t in created_transmitters if t.reliability == 'weak'), None) |
|
||||
if t_weak: |
|
||||
TransmitterOpinion.objects.create( |
|
||||
transmitter=t_weak, |
|
||||
scholar_name=self.create_json_field("Ibn al-Ghadairi", "ابن الغضائری", "Ибн аль-Гадаири"), |
|
||||
opinion_text=self.create_json_field( |
|
||||
"Weak in hadith, extremist in belief.", |
|
||||
"ضعیف در حدیث، غالی در مذهب.", |
|
||||
"Слаб в хадисах, экстремист в убеждениях." |
|
||||
), |
|
||||
status=TransmitterOpinion.OpinionStatus.REJECTED |
|
||||
) |
|
||||
|
opinion_texts = [ |
||||
|
{"en": "He is trustworthy and reliable.", "ar": "هو ثقة ثبت.", "fa": "او ثقه و مورد اعتماد است."}, |
||||
|
{"en": "His memory was weak in later years.", "ar": "كان سيء الحفظ في آخره.", "fa": "حافظه او در اواخر عمر ضعیف بود."}, |
||||
|
{"en": "Unknown status.", "ar": "مجهول الحال.", "fa": "مجهول است."}, |
||||
|
{"en": "Highly praised by scholars.", "ar": "ممدوح عند العلماء.", "fa": "مورد ستایش علما است."}, |
||||
|
] |
||||
|
|
||||
# --------------------------------------------------------- |
|
||||
# 4. Create Original Texts |
|
||||
# --------------------------------------------------------- |
|
||||
self.stdout.write("Adding Original Texts...") |
|
||||
if created_transmitters: |
|
||||
t_author = created_transmitters[1] # Muhammad bin Muslim |
|
||||
TransmitterOriginalText.objects.create( |
|
||||
transmitter=t_author, |
|
||||
title=self.create_json_field( |
|
||||
"Book of Four Hundred Problems", |
|
||||
"کتاب چهارصد مسئله", |
|
||||
"Книга четырехсот вопросов" |
|
||||
), |
|
||||
text=self.create_json_field( |
|
||||
"Content of the book regarding jurisprudence...", |
|
||||
"محتوای کتاب در مورد فقه...", |
|
||||
"Содержание книги по исламскому праву..." |
|
||||
), |
|
||||
translation=self.create_json_field( |
|
||||
"English Translation...", |
|
||||
"ترجمه فارسی...", |
|
||||
"Русский перевод..." |
|
||||
), |
|
||||
) |
|
||||
|
book_titles = [ |
||||
|
{"en": "Book of Traditions", "ar": "كتاب الحديث", "fa": "کتاب حدیث"}, |
||||
|
{"en": "Treatise on Rights", "ar": "رسالة الحقوق", "fa": "رساله حقوق"}, |
||||
|
{"en": "The Clarification", "ar": "التبين", "fa": "تبیین"}, |
||||
|
{"en": "Collection of Virtues", "ar": "مجموع الفضائل", "fa": "مجموعه فضائل"}, |
||||
|
] |
||||
|
|
||||
|
def make_json_field(data_dict): |
||||
|
"""Converts simple dict {'en': 'X', 'fa': 'Y'} to your model's JSON structure""" |
||||
|
return [ |
||||
|
{"language_code": "en", "text": data_dict.get("en", "")}, |
||||
|
{"language_code": "ar", "text": data_dict.get("ar", "")}, |
||||
|
{"language_code": "fa", "text": data_dict.get("fa", "")}, |
||||
|
] |
||||
|
|
||||
# --------------------------------------------------------- |
# --------------------------------------------------------- |
||||
# 5. Link Transmitters to Hadis |
|
||||
|
# 3. Creation Loop |
||||
# --------------------------------------------------------- |
# --------------------------------------------------------- |
||||
self.stdout.write("Linking Transmitters to Hadis (1877-1888)...") |
|
||||
|
|
||||
target_hadis_ids = range(1877, 1889) |
|
||||
|
|
||||
for hadis_id in target_hadis_ids: |
|
||||
try: |
|
||||
hadis_obj = Hadis.objects.get(id=hadis_id) |
|
||||
except ObjectDoesNotExist: |
|
||||
self.stdout.write(self.style.WARNING(f"Hadis ID {hadis_id} not found. Skipping.")) |
|
||||
continue |
|
||||
|
counts = {'opinions': 0, 'texts': 0} |
||||
|
|
||||
HadisTransmitter.objects.filter(hadis=hadis_obj).delete() |
|
||||
|
with transaction.atomic(): |
||||
|
for t in transmitters: |
||||
|
self.stdout.write(f"Processing {t.full_name[0]['text'] if t.full_name else t.id}...") |
||||
|
|
||||
# Create a random chain of 3 transmitters |
|
||||
chain_length = 3 |
|
||||
chain_narrators = random.sample(created_transmitters, min(len(created_transmitters), chain_length)) |
|
||||
|
# --- A. Create TransmitterOpinion (1 to 2 per person) --- |
||||
|
for _ in range(random.randint(1, 2)): |
||||
|
scholar = random.choice(scholars) |
||||
|
text = random.choice(opinion_texts) |
||||
|
status = random.choice(statuses) |
||||
|
|
||||
for index, narrator in enumerate(chain_narrators): |
|
||||
layer_obj = NarratorLayer.objects.get(number=5-index) if index < 5 else None |
|
||||
|
|
||||
# Get or create reliable status |
|
||||
reliable_status, created = TransmitterReliability.objects.get_or_create( |
|
||||
slug='reliable', |
|
||||
defaults={ |
|
||||
'title': self.create_json_field('Reliable', 'موثوق', 'Надежный'), |
|
||||
'color': 'green' |
|
||||
} |
|
||||
|
TransmitterOpinion.objects.create( |
||||
|
transmitter=t, |
||||
|
scholar_name=make_json_field(scholar), |
||||
|
opinion_text=make_json_field(text), |
||||
|
status=status |
||||
) |
) |
||||
|
counts['opinions'] += 1 |
||||
|
|
||||
|
# --- B. Create TransmitterOriginalText (1 to 2 per person) --- |
||||
|
for _ in range(random.randint(1, 2)): |
||||
|
title = random.choice(book_titles) |
||||
|
# Simple dummy text |
||||
|
body = { |
||||
|
"en": f"This is an excerpt from {title['en']}...", |
||||
|
"ar": f"هذا مقتطف من {title['ar']}...", |
||||
|
"fa": f"این بخشی از {title['fa']} است..." |
||||
|
} |
||||
|
|
||||
HadisTransmitter.objects.create( |
|
||||
hadis=hadis_obj, |
|
||||
transmitter=narrator, |
|
||||
narrator_layer=layer_obj, |
|
||||
order=index + 1, |
|
||||
status=reliable_status, |
|
||||
is_gap=False |
|
||||
|
TransmitterOriginalText.objects.create( |
||||
|
transmitter=t, |
||||
|
title=make_json_field(title), |
||||
|
text=make_json_field(body), |
||||
|
translation=make_json_field(body), # Using same text for translation as placeholder |
||||
|
# Note: 'slug' and 'share_link' are handled by your model's save() method automatically |
||||
) |
) |
||||
|
counts['texts'] += 1 |
||||
|
|
||||
self.stdout.write(f"Created chain for Hadis {hadis_id} with {len(chain_narrators)} transmitters.") |
|
||||
|
|
||||
self.stdout.write(self.style.SUCCESS("--- Mock Data Generation Complete ---")) |
|
||||
|
self.stdout.write(self.style.SUCCESS( |
||||
|
f"Done! Created {counts['opinions']} Opinions and {counts['texts']} Original Texts." |
||||
|
)) |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue