8 changed files with 416 additions and 23 deletions
-
23apps/course/views/admin.py
-
87apps/hadis/docs.py
-
117apps/hadis/management/commands/seed_quran_verses.py
-
48apps/hadis/migrations/0015_categoryquranverse_quransecondarytranslation.py
-
63apps/hadis/models/category.py
-
30apps/hadis/serializers/category.py
-
36apps/hadis/views/category.py
-
35apps/hadis/views/hadis.py
@ -0,0 +1,117 @@ |
|||||
|
# backend/apps/hadis/management/commands/seed_quran_verses.py |
||||
|
|
||||
|
from django.core.management.base import BaseCommand |
||||
|
from django.db import transaction |
||||
|
from apps.hadis.models import HadisCategory |
||||
|
from apps.hadis.models.category import CategoryQuranVerse, QuranSecondaryTranslation |
||||
|
|
||||
|
class Command(BaseCommand): |
||||
|
help = 'Seed default Quran verses and secondary translations for Quran categories that contain hadiths.' |
||||
|
|
||||
|
def handle(self, *args, **options): |
||||
|
self.stdout.write(self.style.WARNING("Starting Quran verse seeding process...")) |
||||
|
|
||||
|
# دیتای پیشفرض آیه |
||||
|
surah_name_json = [ |
||||
|
{"language_code": "en", "title": "Al-Nisa"}, |
||||
|
{"language_code": "ru", "title": "Ан-Ниса"}, |
||||
|
{"language_code": "fa", "title": "سورة النساء"} |
||||
|
] |
||||
|
|
||||
|
ayah_number = "64" |
||||
|
|
||||
|
arabic_text = "وَمَا أَرْسَلْنَا مِنْ رَسُولٍ إِلَّا لِيُطَاعَ بِإِذْنِ اللَّهِ وَلَوْ أَنَّهُمْ إِذْ ظَلَمُوا أَنْفُسَهُمْ جَاءُوكَ فَاسْتَغْفَرُوا اللَّهَ وَاسْتَغْفَرَ لَهُمُ الرَّسُولُ لَوَجَدُوا اللَّهَ تَوَّابًا رَحِيمًا" |
||||
|
|
||||
|
primary_translation_json = [ |
||||
|
{ |
||||
|
"language_code": "en", |
||||
|
"title": "And We did not send any messenger except that he should be obeyed by permission of Allah. And if, when they wronged themselves, they had come to you, [O Muhammad], and asked forgiveness of Allah and the Messenger had asked forgiveness for them, they would have found Allah Accepting of repentance and Merciful." |
||||
|
}, |
||||
|
{ |
||||
|
"language_code": "ru", |
||||
|
"title": "Если бы они, поступив несправедливо по отношению к самим себе, пришли к тебе, чтобы молить прощения у Аллаха и чтобы Посланник молил о прощении для них, то они обнаружили бы, что Аллах — Принимающий покаяние и Милосердный" |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
primary_translator_json = [ |
||||
|
{"language_code": "en", "title": "Tafsir Ibn Kathir"}, |
||||
|
{"language_code": "ru", "title": "Тафсир Ибн Касир"} |
||||
|
] |
||||
|
|
||||
|
# دیتای متن ترجمههای ثانویه (متن برای هر ۳ مورد طبق گفته شما یکی است) |
||||
|
secondary_text_json = [ |
||||
|
{ |
||||
|
"language_code": "en", |
||||
|
"title": 'Shihab Ad-Din Alusi, "Ruh al-maani", vol. 11, p. 195, commentary on the 33rd verse, 33rd surah, research: Ali Abd al-Bari Atiya, Dar al-tubut al-ilmiya, Beirut, Lebanon, first edition, 1415, in 16 volumes (15 volumes and one volume of contents).' |
||||
|
}, |
||||
|
{ |
||||
|
"language_code": "ru", |
||||
|
"title": 'Шихаб ад-Дин Алуси, «Рух аль-маани», т. 11, с. 195, комментарий к 33-му аяту 33-й суры, исследование: Али Абд аль-Бари Атия, Дар аль-тубут аль-ильмия, Бейрут, Ливан, первое издание, 1415 г., в 16 томах (15 томов и один том оглавления).' |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
# لیست مترجمان ثانویه |
||||
|
secondary_translators = [ |
||||
|
[ |
||||
|
{"language_code": "en", "title": "Tafsir Ibn Kathir"}, |
||||
|
{"language_code": "ru", "title": "Тафсир Ибн Касир"} |
||||
|
], |
||||
|
[ |
||||
|
{"language_code": "en", "title": "Tafsir al-Jalalayn"}, |
||||
|
{"language_code": "ru", "title": "Тафсир аль-Джалалайн"} |
||||
|
], |
||||
|
[ |
||||
|
{"language_code": "en", "title": "Saadi Translation"}, |
||||
|
{"language_code": "ru", "title": "Перевод Саади"} |
||||
|
] |
||||
|
] |
||||
|
|
||||
|
# پیدا کردن دستهبندیهایی که منبع آنها قرآن است و حداقل یک حدیثِ فعال دارند |
||||
|
target_categories = HadisCategory.objects.filter( |
||||
|
source_type=HadisCategory.SourceType.QURAN, |
||||
|
hadis__status=True # فیلتر از طریق reverse relation (یک دسته باید حداقل یه حدیث فعال داشته باشه) |
||||
|
).distinct() |
||||
|
|
||||
|
if not target_categories.exists(): |
||||
|
self.stdout.write(self.style.WARNING("No Quran categories with active hadiths found.")) |
||||
|
return |
||||
|
|
||||
|
verses_created = 0 |
||||
|
translations_created = 0 |
||||
|
|
||||
|
with transaction.atomic(): |
||||
|
for category in target_categories: |
||||
|
# ساخت یا آپدیت آیه اصلی برای این کتگوری |
||||
|
verse_obj, created = CategoryQuranVerse.objects.update_or_create( |
||||
|
category=category, |
||||
|
defaults={ |
||||
|
'surah_name': surah_name_json, |
||||
|
'ayah_number': ayah_number, |
||||
|
'arabic_text': arabic_text, |
||||
|
'translation': primary_translation_json, |
||||
|
'translator': primary_translator_json |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
if created: |
||||
|
verses_created += 1 |
||||
|
|
||||
|
# پاک کردن ترجمههای ثانویه قبلی (در صورت وجود) برای جلوگیری از تکرار |
||||
|
verse_obj.secondary_translations.all().delete() |
||||
|
|
||||
|
# ساخت ۳ ترجمه ثانویه |
||||
|
for translator_json in secondary_translators: |
||||
|
QuranSecondaryTranslation.objects.create( |
||||
|
quran_verse=verse_obj, |
||||
|
translation_text=secondary_text_json, |
||||
|
translator=translator_json |
||||
|
) |
||||
|
translations_created += 1 |
||||
|
|
||||
|
self.stdout.write(self.style.SUCCESS(f"Seeded Quran data for category: {category.id}")) |
||||
|
|
||||
|
self.stdout.write( |
||||
|
self.style.SUCCESS( |
||||
|
f"\n🎉 Successfully created/updated {verses_created} Quran Verses and added {translations_created} Secondary Translations!" |
||||
|
) |
||||
|
) |
||||
@ -0,0 +1,48 @@ |
|||||
|
# Generated by Django 5.2.12 on 2026-06-18 11:09 |
||||
|
|
||||
|
import django.db.models.deletion |
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('hadis', '0014_hadiscorrection_priority_and_more'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.CreateModel( |
||||
|
name='CategoryQuranVerse', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('surah_name', models.JSONField(default=list, verbose_name='Surah Name')), |
||||
|
('ayah_number', models.CharField(max_length=50, verbose_name='Ayah Number')), |
||||
|
('arabic_text', models.TextField(verbose_name='Arabic Text')), |
||||
|
('translation', models.JSONField(default=list, verbose_name='Primary Translation')), |
||||
|
('translator', models.JSONField(default=list, verbose_name='Primary Translator')), |
||||
|
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), |
||||
|
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')), |
||||
|
('category', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='quran_verse', to='hadis.hadiscategory', verbose_name='Category')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'Category Quran Verse', |
||||
|
'verbose_name_plural': 'Category Quran Verses', |
||||
|
}, |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='QuranSecondaryTranslation', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('translation_text', models.JSONField(default=list, verbose_name='Translation Text')), |
||||
|
('translator', models.JSONField(default=list, verbose_name='Translator Name')), |
||||
|
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), |
||||
|
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')), |
||||
|
('quran_verse', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='secondary_translations', to='hadis.categoryquranverse', verbose_name='Quran Verse')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'Quran Secondary Translation', |
||||
|
'verbose_name_plural': 'Quran Secondary Translations', |
||||
|
'ordering': ['id'], |
||||
|
}, |
||||
|
), |
||||
|
] |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue