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.
 
 
 
 

105 lines
5.3 KiB

# backend/apps/hadis/management/commands/populate_remaining_data.py
import random
from django.core.management.base import BaseCommand
from django.db import transaction
from django.db.models import Q
from apps.hadis.models import Transmitters, TransmitterRelative, TransmitterOpinion
from apps.hadis.models.transmitter import RELATION_TYPE_MAP
class Command(BaseCommand):
help = 'Populates missing companion_type, default Arabic opinions, and generates 10 random relatives.'
def handle(self, *args, **options):
self.stdout.write(self.style.WARNING("Starting population script..."))
# ==========================================
# 1. Populate Companion Type
# ==========================================
comp_updated = Transmitters.objects.filter(
Q(companion_type__isnull=True) | Q(companion_type="")
).update(companion_type="al-A'la ibn Wasil")
self.stdout.write(self.style.SUCCESS(f"✅ Updated {comp_updated} narrators with companion_type."))
# ==========================================
# 2. Populate Transmitter Opinions (Arabic Text)
# ==========================================
opinions = TransmitterOpinion.objects.all()
opinions_to_update = []
default_ar_text = {"language_code": "ar", "text": "ثقة، وهو أثبت من عبد الرحمن بن مهدي."}
for op in opinions:
if not op.opinion_text:
op.opinion_text = [default_ar_text]
opinions_to_update.append(op)
elif isinstance(op.opinion_text, list):
# بررسی اینکه آیا رکورد عربی وجود دارد یا خیر
has_ar = any(isinstance(item, dict) and item.get('language_code') == 'ar' for item in op.opinion_text)
if not has_ar:
op.opinion_text.append(default_ar_text)
opinions_to_update.append(op)
if opinions_to_update:
TransmitterOpinion.objects.bulk_update(opinions_to_update, ['opinion_text'], batch_size=500)
self.stdout.write(self.style.SUCCESS(f"✅ Updated {len(opinions_to_update)} opinions with default Arabic text."))
else:
self.stdout.write(self.style.SUCCESS("✅ All opinions already have Arabic text."))
# ==========================================
# 3. Populate Relatives (10 per narrator: 5, 4, 1)
# ==========================================
# پیدا کردن راویانی که هیچ نسبتی برایشان ثبت نشده است
narrators_without_relatives = Transmitters.objects.filter(relatives__isnull=True).distinct()
count = narrators_without_relatives.count()
if count == 0:
self.stdout.write(self.style.SUCCESS("✅ All narrators already have relatives."))
return
all_transmitter_ids = list(Transmitters.objects.values_list('id', flat=True))
if not all_transmitter_ids:
self.stdout.write(self.style.ERROR("❌ No transmitters found in DB to link."))
return
# 10 اسم رندوم پیش‌فرض
NAMES = ["عمر", "علي", "فاطمة", "خديجة", "زينب", "حسن", "حسين", "محمد", "أحمد", "عائشة"]
relation_choices = [choice[0] for choice in TransmitterRelative.RelationTypeChoices.choices]
new_relatives = []
for narrator in narrators_without_relatives:
group_sizes = [5, 4, 1]
# انتخاب ۳ نوع رابطه رندوم و متفاوت برای این راوی
selected_types = random.sample(relation_choices, 3)
# بر هم زدن لیست اسم‌ها
shuffled_names = random.sample(NAMES, 10)
# انتخاب ۳ ایندکس رندوم (از بین 0 تا 9) که قرار است به راویان دیگر متصل شوند
linked_indices = set(random.sample(range(10), 3))
current_idx = 0
for i, size in enumerate(group_sizes):
rel_type = selected_types[i]
rel_val = RELATION_TYPE_MAP.get(rel_type, [])
for _ in range(size):
linked_narrator_id = None
# اگر ایندکس فعلی جزو ۳ ایندکس خوش‌شانس بود، یک راوی رندوم به آن متصل کن
if current_idx in linked_indices:
linked_narrator_id = random.choice(all_transmitter_ids)
new_relatives.append(
TransmitterRelative(
related_to=narrator,
relation_type=rel_type,
relation_value=rel_val, # اعمال دستی به دلیل استفاده از bulk_create
name=shuffled_names[current_idx],
narrator_id=linked_narrator_id
)
)
current_idx += 1
with transaction.atomic():
TransmitterRelative.objects.bulk_create(new_relatives, batch_size=1000)
self.stdout.write(self.style.SUCCESS(f"🎉 Successfully created {len(new_relatives)} relatives for {count} narrators!"))