6 changed files with 280 additions and 44 deletions
-
105apps/hadis/management/commands/pop_data.py
-
23apps/hadis/migrations/0027_transmitterrelative_relation_value_and_more.py
-
69apps/hadis/models/transmitter.py
-
27apps/hadis/serializers/hadis.py
-
5apps/hadis/urls.py
-
91apps/hadis/views/transmitter.py
@ -0,0 +1,105 @@ |
|||||
|
# 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!")) |
||||
@ -0,0 +1,23 @@ |
|||||
|
# Generated by Django 5.2.12 on 2026-06-28 14:31 |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('hadis', '0026_transmitterrelative'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AddField( |
||||
|
model_name='transmitterrelative', |
||||
|
name='relation_value', |
||||
|
field=models.JSONField(default=list, verbose_name='Relation Value'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='transmitterrelative', |
||||
|
name='relation_type', |
||||
|
field=models.CharField(choices=[('stepfather', 'Stepfather'), ('stepmother', 'Stepmother'), ('uncles_and_aunts', 'Uncles and aunts'), ('siblings', 'Siblings'), ('parents', 'Parents'), ('nephews_and_nieces', 'Nephews and nieces'), ('children', 'Children'), ('stepchildren', 'Stepchildren'), ('spouses', 'Spouses'), ('cousins', 'Cousins'), ('granduncles_and_grandaunts', 'Granduncles and grandaunts'), ('grandnephews_and_grandnieces', 'Grandnephews and grandnieces'), ('grandchildren_and_great_grandchildren', 'Grandchildren and great-grandchildren'), ('grandparents', 'Grandparents'), ('foster_mother', 'Foster mother'), ('tribe', 'Tribe'), ('foster_children', 'Foster children'), ('in_laws', 'In-laws'), ('students', 'Students'), ('owners_and_masters', 'Owners and masters'), ('other_relatives', 'Other relatives'), ('friends_and_companions', 'Friends and companions'), ('allies', 'Allies'), ('neighbors', 'Neighbors'), ('wards_and_proteges', 'Wards and proteges'), ('cousins_of_parents', 'Cousins of parents'), ('cousins_of_grandparents', 'Cousins of grandparents'), ('cousins_children', 'Cousins children'), ('cousins_grandchildren_and_great_grandchildren', 'Cousins grandchildren and great-grandchildren')], max_length=50, verbose_name='Relation Type'), |
||||
|
), |
||||
|
] |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue