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.1 KiB

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
from apps.hadis.models import Hadis, Transmitters, NarratorLayer, HadisTransmitter
class Command(BaseCommand):
help = 'Seeds HadisTransmitter instances with specific constraints'
def handle(self, *args, **options):
self.stdout.write("Starting HadisTransmitter seeding...")
# ---------------------------------------------------------
# 1. Fetch the specific Objects
# ---------------------------------------------------------
layers = list(NarratorLayer.objects.filter(id__range=(11, 15)))
transmitters = list(Transmitters.objects.filter(id__range=(84, 91)))
# Hadis query
hadis_qs = Hadis.objects.filter(
Q(id__range=(1800, 1852)) | Q(id__range=(1877, 1889))
)
# ---------------------------------------------------------
# 2. Validation
# ---------------------------------------------------------
if len(layers) < 2:
self.stdout.write(self.style.ERROR(f"Need at least 2 NarratorLayers to satisfy constraints, but found {len(layers)}."))
return
if not transmitters:
self.stdout.write(self.style.ERROR("No Transmitters found in range 84-91."))
return
if not hadis_qs.exists():
self.stdout.write(self.style.ERROR("No Hadis found in the specified ranges."))
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_count = 0
self.stdout.write("Beginning processing...")
for i, hadis in enumerate(hadis_qs, 1):
# Print progress every 5 items so you know it's not frozen
if i % 5 == 0:
self.stdout.write(f"Processing {i}/{total_hadis} (Hadis ID: {hadis.id})...")
# Wrap PER ITEM in transaction to avoid long db locks
with transaction.atomic():
# CONSTRAINT 1: Each hadis must have 3-4 transmitters
chain_length = random.randint(3, 4)
if len(transmitters) < chain_length:
self.stdout.write(self.style.WARNING(f"Not enough transmitters. Skipping Hadis {hadis.id}."))
continue
# Pick unique transmitters
selected_transmitters = random.sample(transmitters, chain_length)
# CONSTRAINT 2: Transmitters must be separated to at least 2 narrator layers
# LOGIC FIX: Instead of a while loop, we force the condition explicitly.
# Step A: Pick 2 DISTINCT layers guaranteed
guaranteed_layers = random.sample(layers, 2)
# Step B: Fill the remaining slots (1 or 2 slots) with random layers
remaining_slots = chain_length - 2
other_layers = [random.choice(layers) for _ in range(remaining_slots)]
# Step C: Combine and Shuffle so the distinct ones aren't always first
final_layers = guaranteed_layers + other_layers
random.shuffle(final_layers)
# Create the connections
for index, transmitter in enumerate(selected_transmitters):
HadisTransmitter.objects.create(
hadis=hadis,
transmitter=transmitter,
narrator_layer=final_layers[index],
order=index,
status=transmitter.reliability if hasattr(transmitter, 'reliability') else None
)
created_count += 1
self.stdout.write(self.style.SUCCESS(f"Done! Successfully created {created_count} HadisTransmitter instances."))