""" Django management command to seed mock data for hadith collections, references, and corrections. Place this file in: yourapp/management/commands/seed_hadis.py Usage: python manage.py seed_hadis python manage.py seed_hadis --clear """ import os from pathlib import Path from django.core.management.base import BaseCommand from django.core.files.base import ContentFile from django.utils.text import slugify from django.conf import settings from apps.hadis.models.hadis import ( HadisCollection, HadisInCollection, HadisReference, ReferenceImage, HadisCorrection, Hadis ) from apps.hadis.models.reference import BookReference class Command(BaseCommand): help = 'Seed the database with mock hadith collection and reference data' def add_arguments(self, parser): parser.add_argument( '--clear', action='store_true', help='Clear existing data before seeding', ) def handle(self, *args, **options): if options['clear']: self.stdout.write(self.style.WARNING('Clearing existing hadith data...')) ReferenceImage.objects.all().delete() HadisCorrection.objects.all().delete() HadisReference.objects.all().delete() HadisInCollection.objects.all().delete() HadisCollection.objects.all().delete() self.stdout.write(self.style.SUCCESS('Data cleared successfully!')) # Step 1: Create Hadis Collections self.stdout.write(self.style.SUCCESS('\n📚 Creating Hadis Collections...')) collections_data = [ { "title": "Purification & Prayer", "summary": "Collection of ahadith related to purification (Wudu, Ghusl) and prayer rituals.", "status": True, "order": 1, }, { "title": "Zakat & Charity", "summary": "Ahadith discussing the obligation of zakat and charitable giving in Islam.", "status": True, "order": 2, }, { "title": "Fasting & Ramadan", "summary": "Collection of authentic ahadith about fasting, its virtues, and Ramadan practices.", "status": True, "order": 3, }, { "title": "Hajj & Umrah", "summary": "Ahadith related to the pilgrimage to Mecca and the spiritual practices involved.", "status": True, "order": 4, }, { "title": "Ethics & Morality", "summary": "Ahadith emphasizing Islamic ethics, good character, and moral conduct.", "status": True, "order": 5, }, { "title": "Knowledge & Learning", "summary": "Collection emphasizing the importance of seeking knowledge in Islam.", "status": True, "order": 6, }, { "title": "Family & Relations", "summary": "Ahadith about family relationships, rights of parents, spouses, and children.", "status": True, "order": 7, }, { "title": "Business & Trade", "summary": "Ahadith related to ethical business practices and commerce in Islam.", "status": True, "order": 8, }, ] collections = {} for collection_data in collections_data: collection, created = HadisCollection.objects.get_or_create( title=collection_data['title'], defaults=collection_data ) collections[collection_data['title']] = collection status = '✓ Created' if created else '• Updated' self.stdout.write(f"{status}: {collection.title}") # Step 2: Get book references (we'll use all available books) self.stdout.write(self.style.SUCCESS('\n📖 Getting Book References...')) book_references = BookReference.objects.all() if not book_references.exists(): self.stdout.write(self.style.WARNING('⚠️ No book references found. Run seed_books first!')) return book_references_list = list(book_references) self.stdout.write(f"✓ Found {len(book_references_list)} book references") # Step 3: Create Hadis References self.stdout.write(self.style.SUCCESS('\n🔗 Creating Hadis References...')) hadis_ids = list(range(1800, 1853)) reference_descriptions = [ "This hadith is recorded in the collection with full chain of narration.", "The narration is found in multiple reliable sources with slight variations.", "This is a widely transmitted hadith with consistent narration across sources.", "The hadith is reported with authentic chain and acceptable wording.", "This tradition appears in the primary sources with confirmed authenticity.", "The narration demonstrates the scholarly consensus on this issue.", "The hadith is part of the foundational traditions in this category.", "This is one of the most frequently cited ahadith on this topic.", ] hadis_references = {} reference_counter = 0 for idx, hadis_id in enumerate(hadis_ids): # Get or create Hadis object try: hadis = Hadis.objects.get(pk=hadis_id) except Hadis.DoesNotExist: self.stdout.write( self.style.WARNING(f"⚠️ Hadis with ID {hadis_id} not found, skipping...") ) continue # Randomly assign 1-3 book references per hadith num_refs = (idx % 3) + 1 selected_books = book_references_list[idx % len(book_references_list):(idx % len(book_references_list)) + num_refs] for book_idx, book_ref in enumerate(selected_books): hadis_ref, created = HadisReference.objects.get_or_create( hadis=hadis, book_reference=book_ref, defaults={ 'description': reference_descriptions[reference_counter % len(reference_descriptions)] } ) if created: hadis_references[hadis_id] = hadis_ref reference_counter += 1 self.stdout.write( self.style.SUCCESS( f"✓ Reference: Hadis {hadis_id} <- {book_ref.title}" ) ) # Step 4: Add Reference Images self.stdout.write(self.style.SUCCESS('\n🖼️ Adding Reference Images...')) ref_images_added = self._add_reference_images(hadis_references) self.stdout.write(f"✓ Added {ref_images_added} reference images") # Step 5: Create Hadis In Collection self.stdout.write(self.style.SUCCESS('\n📋 Adding Hadis to Collections...')) collection_assignments = [ { "collection_title": "Purification & Prayer", "hadis_ids": [1800, 1801, 1802, 1803, 1804], }, { "collection_title": "Zakat & Charity", "hadis_ids": [1805, 1806, 1807, 1808], }, { "collection_title": "Fasting & Ramadan", "hadis_ids": [1809, 1810, 1811, 1812, 1813], }, { "collection_title": "Hajj & Umrah", "hadis_ids": [1814, 1815, 1816, 1817], }, { "collection_title": "Ethics & Morality", "hadis_ids": [1818, 1819, 1820, 1821, 1822, 1823], }, { "collection_title": "Knowledge & Learning", "hadis_ids": [1824, 1825, 1826, 1827], }, { "collection_title": "Family & Relations", "hadis_ids": [1828, 1829, 1830, 1831, 1832, 1833], }, { "collection_title": "Business & Trade", "hadis_ids": [1834, 1835, 1836, 1837, 1838], }, ] hadis_in_collection_count = 0 for assignment in collection_assignments: collection = collections.get(assignment['collection_title']) if not collection: continue for order, hadis_id in enumerate(assignment['hadis_ids']): try: hadis = Hadis.objects.get(pk=hadis_id) hic, created = HadisInCollection.objects.get_or_create( hadis=hadis, collection=collection, defaults={'order': order} ) if created: hadis_in_collection_count += 1 self.stdout.write( self.style.SUCCESS( f"✓ Added Hadis {hadis_id} to {collection.title} (Order {order})" ) ) except Hadis.DoesNotExist: pass # Step 6: Create Hadis Corrections self.stdout.write(self.style.SUCCESS('\n✏️ Creating Hadis Corrections...')) corrections_data = [ { "hadis_id": 1800, "title": "Clarification on Wudu Sequence", "description": "Some scholars differ on the exact sequence of washing body parts during ablution.", "translation": [ {"lang": "en", "text": "The order of washing in wudu should follow the established practice."}, {"lang": "ar", "text": "ترتيب غسل الأعضاء في الوضوء يجب أن يتبع السنة المثبتة."} ], }, { "hadis_id": 1802, "title": "Prayer Time Variations", "description": "Different schools of thought have varying opinions on prayer times.", "translation": [ {"lang": "en", "text": "Prayer times may vary slightly depending on geographical location."}, {"lang": "ar", "text": "أوقات الصلاة قد تختلف قليلاً حسب الموقع الجغرافي."} ], }, { "hadis_id": 1805, "title": "Zakat Calculation Methods", "description": "Various methods exist for calculating zakat on different types of wealth.", "translation": [ {"lang": "en", "text": "The calculation of zakat follows specific rules for different assets."}, {"lang": "ar", "text": "حساب الزكاة يتبع قواعد محددة لأنواع مختلفة من الأموال."} ], }, { "hadis_id": 1810, "title": "Fasting in Different Climates", "description": "Scholars discuss fasting practices in regions with extreme daylight variations.", "translation": [ {"lang": "en", "text": "Fasting guidelines adapt to extreme daylight conditions in certain regions."}, {"lang": "ar", "text": "تتكيف إرشادات الصيام مع ظروف الإضاءة الشديدة في بعض المناطق."} ], }, { "hadis_id": 1815, "title": "Hajj Routes and Methods", "description": "Multiple routes and methods for performing Hajj rituals are recognized.", "translation": [ {"lang": "en", "text": "Different schools recognize various methods for performing Hajj rituals."}, {"lang": "ar", "text": "تعترف المذاهب المختلفة بطرق متعددة لأداء مناسك الحج."} ], }, { "hadis_id": 1820, "title": "Ethical Conduct in Commerce", "description": "Islamic principles of honesty and fairness in business transactions.", "translation": [ {"lang": "en", "text": "Islamic business ethics emphasize honesty and mutual fairness."}, {"lang": "ar", "text": "تؤكد أخلاقيات الأعمال الإسلامية على الصدق والإنصاف المتبادل."} ], }, { "hadis_id": 1825, "title": "Hadith Authentication Methods", "description": "Scholars use various methodologies for authenticating hadith narrations.", "translation": [ {"lang": "en", "text": "Hadith scholars employ rigorous methodology in authentication."}, {"lang": "ar", "text": "يستخدم علماء الحديث منهجية صارمة في التحقق من الصحة."} ], }, { "hadis_id": 1830, "title": "Family Rights and Obligations", "description": "The Islamic framework defines rights and responsibilities within families.", "translation": [ {"lang": "en", "text": "Islam defines clear rights and obligations for family members."}, {"lang": "ar", "text": "يحدد الإسلام حقوقاً والتزامات واضحة لأفراد الأسرة."} ], }, ] corrections_count = 0 for correction_data in corrections_data: hadis_id = correction_data.pop('hadis_id') try: hadis = Hadis.objects.get(pk=hadis_id) correction, created = HadisCorrection.objects.get_or_create( hadis=hadis, title=correction_data['title'], defaults=correction_data ) if created: corrections_count += 1 self.stdout.write( self.style.SUCCESS( f"✓ Correction created: {correction_data['title']} for Hadis {hadis_id}" ) ) except Hadis.DoesNotExist: pass self.stdout.write( self.style.SUCCESS( f'\n✓ Successfully seeded hadith data!' ) ) self._print_summary( collections, hadis_in_collection_count, len(hadis_references), ref_images_added, corrections_count ) def _add_reference_images(self, hadis_references): """Add reference images from seeds/images folder""" images_added = 0 ref_images = ['ref1.png', 'ref2.png', 'ref3.png', 'ref4.png'] image_counter = 0 for hadis_id, hadis_ref in hadis_references.items(): # Add 1-2 images per reference num_images = (image_counter % 2) + 1 for img_idx in range(num_images): image_name = ref_images[image_counter % len(ref_images)] image_path = self._get_image_path(image_name) if image_path and os.path.exists(image_path): # Check if image already exists existing_images_count = hadis_ref.images.count() with open(image_path, 'rb') as img_file: ref_image, created = ReferenceImage.objects.get_or_create( reference=hadis_ref, priority=existing_images_count + img_idx, defaults={ 'thumbnail': None } ) if created: # Save the image file ref_image.thumbnail.save( image_name, ContentFile(img_file.read()), save=True ) images_added += 1 self.stdout.write( self.style.SUCCESS( f"✓ Image added: {image_name} to Hadis {hadis_id} reference" ) ) image_counter += 1 return images_added def _get_image_path(self, image_name): """Find the image file for the given image name""" possible_paths = [ Path('seeds/images') / image_name, Path('seed_data/images') / image_name, Path('static/images') / image_name, Path('.') / 'seeds' / 'images' / image_name, ] for path in possible_paths: if path.exists(): return path return None def _print_summary(self, collections, hadis_in_collection_count, references_count, images_count, corrections_count): """Print a summary of created data""" self.stdout.write("\n" + "="*70) self.stdout.write(self.style.SUCCESS("HADITH DATABASE SUMMARY")) self.stdout.write("="*70) collections_count = HadisCollection.objects.count() total_hadis_in_collection = HadisInCollection.objects.count() total_references = HadisReference.objects.count() total_ref_images = ReferenceImage.objects.count() total_corrections = HadisCorrection.objects.count() self.stdout.write(f"📚 Hadis Collections: {collections_count}") self.stdout.write(f"📋 Hadis in Collections: {total_hadis_in_collection}") self.stdout.write(f"🔗 Hadis References: {total_references}") self.stdout.write(f"🖼️ Reference Images: {total_ref_images}") self.stdout.write(f"✏️ Hadis Corrections: {total_corrections}") self.stdout.write("\n" + "="*70) self.stdout.write(self.style.WARNING("Collections Created:")) self.stdout.write("="*70) for collection_title in list(collections.keys()): hadis_count = HadisInCollection.objects.filter( collection__title=collection_title ).count() self.stdout.write(f" • {collection_title} ({hadis_count} ahadith)") self.stdout.write("="*70 + "\n")