import random import time from django.core.management.base import BaseCommand from django.db import transaction from django.db.models import Q # REPLACE 'your_app' with your actual app name (e.g., apps.hadis.models) from apps.hadis.models import Hadis, Transmitters, NarratorLayer, HadisTransmitter class Command(BaseCommand): help = 'Seeds HadisTransmitter instances for ALL Hadis with 5+ transmitters spanning 2-3 layers' def handle(self, *args, **options): self.stdout.write("Starting Global HadisTransmitter seeding...") # --------------------------------------------------------- # 1. Fetch ALL Objects # --------------------------------------------------------- layers = list(NarratorLayer.objects.all()) transmitters = list(Transmitters.objects.all()) # Fetch all Hadis records hadis_qs = Hadis.objects.all() # --------------------------------------------------------- # 2. Validation # --------------------------------------------------------- if len(layers) < 3: self.stdout.write(self.style.ERROR(f"Need at least 3 NarratorLayers to satisfy constraints, but found {len(layers)}.")) return if len(transmitters) < 5: self.stdout.write(self.style.ERROR(f"Need at least 5 Transmitters to satisfy chain length, but found {len(transmitters)}.")) return if not hadis_qs.exists(): self.stdout.write(self.style.ERROR("No Hadis found in the database.")) return total_hadis = hadis_qs.count() self.stdout.write(f"Found {len(layers)} Layers, {len(transmitters)} Transmitters, and {total_hadis} Hadis.") # --------------------------------------------------------- # 3. Creation Loop # --------------------------------------------------------- created_links_count = 0 self.stdout.write("Beginning processing...") for i, hadis in enumerate(hadis_qs, 1): # Progress indicator if i % 100 == 0: self.stdout.write(f"Processing {i}/{total_hadis}...") with transaction.atomic(): # Clean existing transmitters for this hadis to avoid duplicates/conflicts if re-running # Remove this line if you want to APPEND to existing data instead of resetting HadisTransmitter.objects.filter(hadis=hadis).delete() # CONSTRAINT 1: Chain length must be at least 5 (let's do 5 to 7) chain_length = random.randint(5, 7) # CONSTRAINT 2: Must have at least 2-3 narrator layers target_unique_layers = random.randint(2, 3) # --- Logic to Select Transmitters and Layers --- # A. Select Transmitters selected_transmitters = random.sample(transmitters, chain_length) # B. Select Layers # First, pick the 'mandatory' unique layers to satisfy the constraint mandatory_layers = random.sample(layers, target_unique_layers) # Second, fill the remaining slots in the chain remaining_slots = chain_length - target_unique_layers # We can pick from ANY layer for the remaining slots (including the mandatory ones) other_layers = [random.choice(layers) for _ in range(remaining_slots)] # Combine and Shuffle final_layers_pool = mandatory_layers + other_layers random.shuffle(final_layers_pool) # --- Create Connections --- for index, transmitter in enumerate(selected_transmitters): HadisTransmitter.objects.create( hadis=hadis, transmitter=transmitter, narrator_layer=final_layers_pool[index], order=index, # Check if transmitter has 'reliability' (ForeignKey) or if it's a direct field status=transmitter.reliability if hasattr(transmitter, 'reliability') else None ) created_links_count += 1 self.stdout.write(self.style.SUCCESS(f"Done! Created {created_links_count} HadisTransmitter connections for {total_hadis} Hadiths."))