# 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!" ) )