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
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."))
|