You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

91 lines
4.4 KiB

# backend/apps/hadis/management/commands/seed_hadis_chains.py
import random
from django.core.management.base import BaseCommand
from django.db import transaction
from apps.hadis.models import Hadis, Transmitters, HadisTransmitter, NarratorLayer, TransmitterReliability
class Command(BaseCommand):
help = 'Seeds random transmission chains (HadisTransmitter) for all existing Hadiths.'
def handle(self, *args, **options):
self.stdout.write(self.style.WARNING("Checking Hadiths without transmission chains..."))
# دریافت تمام دیتاهای پایه
hadiths = list(Hadis.objects.filter(transmitters__isnull=True).distinct())
narrators = list(Transmitters.objects.all())
layers = list(NarratorLayer.objects.all())
reliabilities = list(TransmitterReliability.objects.all())
# بررسی وجود دیتای کافی
if not hadiths:
self.stdout.write(self.style.SUCCESS("All Hadiths already have transmission chains! Nothing to seed."))
return
if len(narrators) < 4:
self.stdout.write(self.style.ERROR("Not enough Transmitters found. Please add at least 4 narrators."))
return
self.stdout.write(f"Found {len(hadiths)} Hadiths without transmitters. Generating chains...")
links_to_create = []
# ساخت زنجیره‌ها
for hadis in hadiths:
hadis_layers = list(hadis.narrator_layers.all().order_by('number'))
if not hadis_layers:
layer1 = NarratorLayer.objects.create(
hadis=hadis,
number=1,
name=[{"language_code": "en", "text": "Primary Transmitters"}],
description=[{"language_code": "en", "text": "Primary layer of transmitters."}],
slug=f"hadis-{hadis.id}-l1-primary"
)
layer2 = NarratorLayer.objects.create(
hadis=hadis,
number=2,
name=[{"language_code": "en", "text": "Secondary Transmitters"}],
description=[{"language_code": "en", "text": "Secondary layer of transmitters."}],
slug=f"hadis-{hadis.id}-l2-secondary"
)
hadis_layers = [layer1, layer2]
num_layers = len(hadis_layers)
# هر حدیث بین 2 تا 3 لایه/زنجیره (Chain) داشته باشد
num_chains = random.randint(2, 3)
for chain_idx in range(num_chains):
# هر زنجیره بین 4 تا 6 راوی داشته باشد
num_narrators = random.randint(4, min(6, len(narrators)))
# انتخاب رندوم چند راوی برای این زنجیره بدون تکرار
chain_narrators = random.sample(narrators, num_narrators)
for order_idx, narrator in enumerate(chain_narrators):
assigned_layer = hadis_layers[min(num_layers - 1, order_idx // 2)] if num_layers > 1 else hadis_layers[0]
random_status = random.choice(reliabilities) if reliabilities else None
link = HadisTransmitter(
hadis=hadis,
transmitter=narrator,
chain_index=chain_idx,
order=order_idx, # ترتیب قرارگیری راوی در این زنجیره
narrator_layer=assigned_layer,
status=random_status,
is_gap=random.choice([True, False, False, False]) # احتمال کم برای گپ (انقطاع سند)
)
links_to_create.append(link)
# ذخیره دسته‌جمعی (Bulk Create) برای پرفورمنس بسیار بالاتر
with transaction.atomic():
# برای جلوگیری از محدودیت حافظه، در دسته‌های 1000 تایی ذخیره می‌کنیم
batch_size = 1000
for i in range(0, len(links_to_create), batch_size):
HadisTransmitter.objects.bulk_create(links_to_create[i:i + batch_size])
self.stdout.write(
self.style.SUCCESS(
f"Successfully created {len(links_to_create)} random narrator links across {len(hadiths)} Hadiths!"
)
)