9 changed files with 215 additions and 24 deletions
-
9apps/hadis/admin/transmitter.py
-
91apps/hadis/management/commands/seed_hadis_transmitter.py
-
24apps/hadis/management/commands/seed_transmitters.py
-
26apps/hadis/migrations/0081_alter_hadistransmitter_status.py
-
16apps/hadis/migrations/0082_remove_hadistransmitter_status.py
-
15apps/hadis/migrations/0083_auto_20251224_1214.py
-
26apps/hadis/migrations/0084_hadistransmitter_status.py
-
15apps/hadis/models/transmitter.py
-
17apps/hadis/serializers/hadis.py
@ -0,0 +1,91 @@ |
|||
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.")) |
|||
@ -0,0 +1,26 @@ |
|||
# Generated by Django 4.2.27 on 2025-12-24 11:58 |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
dependencies = [ |
|||
("hadis", "0080_transmitteropinion_status"), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AlterField( |
|||
model_name="hadistransmitter", |
|||
name="status", |
|||
field=models.ForeignKey( |
|||
blank=True, |
|||
help_text="Reliability status of the narrator", |
|||
null=True, |
|||
on_delete=django.db.models.deletion.SET_NULL, |
|||
related_name="hadis_transmitters", |
|||
to="hadis.transmitterreliability", |
|||
verbose_name="reliability status", |
|||
), |
|||
), |
|||
] |
|||
@ -0,0 +1,16 @@ |
|||
# Generated by Django 4.2.27 on 2025-12-24 12:11 |
|||
|
|||
from django.db import migrations |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
dependencies = [ |
|||
("hadis", "0081_alter_hadistransmitter_status"), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.RemoveField( |
|||
model_name="hadistransmitter", |
|||
name="status", |
|||
), |
|||
] |
|||
@ -0,0 +1,15 @@ |
|||
from django.db import migrations |
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('hadis', '0082_remove_hadistransmitter_status'), # Keep your actual dependency here |
|||
] |
|||
|
|||
operations = [ |
|||
# This tells Django: "Run this SQL command, but don't try to update your internal model state" |
|||
migrations.RunSQL( |
|||
sql="ALTER TABLE hadis_hadistransmitter DROP COLUMN status;", |
|||
reverse_sql="ALTER TABLE hadis_hadistransmitter ADD COLUMN status varchar(255);" # Optional fallback |
|||
), |
|||
] |
|||
@ -0,0 +1,26 @@ |
|||
# Generated by Django 4.2.27 on 2025-12-24 12:32 |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
dependencies = [ |
|||
("hadis", "0083_auto_20251224_1214"), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AddField( |
|||
model_name="hadistransmitter", |
|||
name="status", |
|||
field=models.ForeignKey( |
|||
blank=True, |
|||
help_text="Reliability status of the narrator", |
|||
null=True, |
|||
on_delete=django.db.models.deletion.SET_NULL, |
|||
related_name="hadis_transmitters", |
|||
to="hadis.transmitterreliability", |
|||
verbose_name="reliability status", |
|||
), |
|||
), |
|||
] |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue