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.
93 lines
4.3 KiB
93 lines
4.3 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 (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."))
|