From a28563e9a8c5053741be15b4ad92f3c410a78878 Mon Sep 17 00:00:00 2001 From: mohsentaba Date: Wed, 17 Dec 2025 10:14:23 +0330 Subject: [PATCH] hadis sync N+1 fixed --- apps/hadis/docs.py | 8 +- apps/hadis/management/commands/seed_books.py | 276 ++++++++ .../management/commands/seed_category_data.py | 497 ++++++++++++++ .../hadis/management/commands/seed_hadis_2.py | 432 ++++++++++++ .../management/commands/seed_transmitters.py | 613 ++++++++++++++++++ apps/hadis/serializers/hadis.py | 29 +- apps/hadis/views/hadis.py | 4 +- scripts/__init__.py | 0 scripts/seed_books.py | 276 ++++++++ seeds/images/image 1208.png | Bin 0 -> 16638 bytes seeds/images/ref1.png | Bin 0 -> 60583 bytes seeds/images/ref2.png | Bin 0 -> 16638 bytes seeds/images/ref3.png | Bin 0 -> 8964 bytes seeds/images/ref4.png | Bin 0 -> 16638 bytes 14 files changed, 2115 insertions(+), 20 deletions(-) create mode 100644 apps/hadis/management/commands/seed_books.py create mode 100644 apps/hadis/management/commands/seed_category_data.py create mode 100644 apps/hadis/management/commands/seed_hadis_2.py create mode 100644 apps/hadis/management/commands/seed_transmitters.py create mode 100644 scripts/__init__.py create mode 100644 scripts/seed_books.py create mode 100644 seeds/images/image 1208.png create mode 100644 seeds/images/ref1.png create mode 100644 seeds/images/ref2.png create mode 100644 seeds/images/ref3.png create mode 100644 seeds/images/ref4.png diff --git a/apps/hadis/docs.py b/apps/hadis/docs.py index 97e07ed..b1d1878 100644 --- a/apps/hadis/docs.py +++ b/apps/hadis/docs.py @@ -1105,11 +1105,11 @@ transmitter_original_text_swagger = swagger_auto_schema( "translation": [ { "language_code": "en", - "title": "Actions are but by intention, and every person will have what they intended. So whoever emigrated for Allah and His Messenger, then his emigration is for Allah and His Messenger. And whoever emigrated for worldly gain or to marry a woman, then his emigration is for that which he emigrated." + "text": "Actions are but by intention, and every person will have what they intended. So whoever emigrated for Allah and His Messenger, then his emigration is for Allah and His Messenger. And whoever emigrated for worldly gain or to marry a woman, then his emigration is for that which he emigrated." }, { "language_code": "fa", - "title": "اعمال به نیت ها است و هر کس آنچه را که قصد کرده است خواهد داشت. پس هر کس برای خدا و پیامبرش هجرت کند، هجرت او برای خدا و پیامبرش است. و هر کس برای منافع دنیوی یا ازدواج با زنی هجرت کند، هجرت او برای همان چیزی است که برای آن هجرت کرده است." + "text": "اعمال به نیت ها است و هر کس آنچه را که قصد کرده است خواهد داشت. پس هر کس برای خدا و پیامبرش هجرت کند، هجرت او برای خدا و پیامبرش است. و هر کس برای منافع دنیوی یا ازدواج با زنی هجرت کند، هجرت او برای همان چیزی است که برای آن هجرت کرده است." } ], "share_link": "http://example.com/narrators/56/texts/1" @@ -1121,11 +1121,11 @@ transmitter_original_text_swagger = swagger_auto_schema( "translation": [ { "language_code": "en", - "title": "Seeking knowledge is obligatory upon every Muslim, male and female" + "text": "Seeking knowledge is obligatory upon every Muslim, male and female" }, { "language_code": "fa", - "title": "طلب علم بر هر مسلمان و مسلمانی واجب است" + "text": "طلب علم بر هر مسلمان و مسلمانی واجب است" } ], "share_link": "http://example.com/narrators/56/texts/2" diff --git a/apps/hadis/management/commands/seed_books.py b/apps/hadis/management/commands/seed_books.py new file mode 100644 index 0000000..a321a3c --- /dev/null +++ b/apps/hadis/management/commands/seed_books.py @@ -0,0 +1,276 @@ +""" +Django management command to seed mock data for hadith book references. +Place this file in: yourapp/management/commands/seed_books.py + +Usage: python manage.py seed_books +""" + +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 apps.hadis.models.reference import ( + BookReference, + BookReferenceImage, + BookAuthor, + BookAttribute +) + + +class Command(BaseCommand): + help = 'Seed the database with mock hadith book 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 data...')) + BookAttribute.objects.all().delete() + BookReferenceImage.objects.all().delete() + BookAuthor.objects.all().delete() + BookReference.objects.all().delete() + self.stdout.write(self.style.SUCCESS('Data cleared successfully!')) + + # Create authors first + authors_data = [ + {"name": "Imam Muhammad al-Bukhari"}, + {"name": "Imam Muslim ibn al-Hajjaj"}, + {"name": "Imam Abu Dawood as-Sijistani"}, + {"name": "Imam At-Tirmidhi"}, + {"name": "Imam Ibn Majah"}, + {"name": "Imam Ahmad ibn Hanbal"}, + {"name": "Imam Al-Hakim"}, + {"name": "Imam Ad-Daraqutni"}, + ] + + authors = {} + for author_data in authors_data: + author, created = BookAuthor.objects.get_or_create( + name=author_data['name'] + ) + authors[author_data['name']] = author + if created: + self.stdout.write(self.style.SUCCESS(f'Created author: {author.name}')) + + # Create book references + books_data = [ + { + "title": "Sahih al-Bukhari", + "description": "The most authentic collection of hadith, compiled by Imam Muhammad al-Bukhari. Contains 7,563 ahadith.", + "language": "Arabic", + "isbn": "978-1-86043-009-6", + "volume": "9 volumes", + "year_of_publication": "1870", + "number_page": 1200, + "publisher": "Dar al-Kutub al-Ilmiyah", + "rate": 5.00, + "authors": ["Imam Muhammad al-Bukhari"], + "image_order": 1, + "attributes": { + "Collection Type": "Hadith Compilation", + "Number of Hadith": "7,563", + "Classification": "6 Books", + "Authenticity Grade": "Sahih (Authentic)", + "Compilation Period": "16 years", + } + }, + { + "title": "Sahih Muslim", + "description": "Second most authentic hadith collection compiled by Imam Muslim ibn al-Hajjaj. Contains 9,200 traditions.", + "language": "Arabic", + "isbn": "978-1-86043-010-2", + "volume": "5 volumes", + "year_of_publication": "1875", + "number_page": 1500, + "publisher": "Dar Ihya at-Turath al-Arabi", + "rate": 4.95, + "authors": ["Imam Muslim ibn al-Hajjaj"], + "image_order": 2, + "attributes": { + "Collection Type": "Hadith Compilation", + "Number of Hadith": "9,200", + "Classification": "43 Books", + "Authenticity Grade": "Sahih (Authentic)", + "Unique Hadith": "Approximately 4,000", + } + }, + { + "title": "Sunan Abu Dawood", + "description": "A comprehensive collection of hadith containing jurisprudential material, compiled by Imam Abu Dawood as-Sijistani.", + "language": "Arabic", + "isbn": "978-1-86043-011-9", + "volume": "4 volumes", + "year_of_publication": "1880", + "number_page": 1400, + "publisher": "Islamic Digital Library", + "rate": 4.80, + "authors": ["Imam Abu Dawood as-Sijistani"], + "image_order": 3, + "attributes": { + "Collection Type": "Sunan (Practice)", + "Number of Hadith": "5,274", + "Focus": "Jurisprudential Traditions", + "Number of Books": "43", + "Authenticity Grade": "Hasan to Sahih", + } + }, + { + "title": "Jami' at-Tirmidhi", + "description": "A major collection of hadith compiled by Imam At-Tirmidhi with his commentary and grading of narrations.", + "language": "Arabic", + "isbn": "978-1-86043-012-6", + "volume": "5 volumes", + "year_of_publication": "1892", + "number_page": 1350, + "publisher": "Dar ar-Risalah al-Alamiyah", + "rate": 4.85, + "authors": ["Imam At-Tirmidhi"], + "image_order": 4, + "attributes": { + "Collection Type": "Jami (Comprehensive)", + "Number of Hadith": "3,956", + "Notable Feature": "Grades each hadith", + "Categories": "63 Chapters", + "Authenticity Grade": "Various Grades", + } + }, + { + "title": "Sunan Ibn Majah", + "description": "A collection of hadith compiled by Imam Ibn Majah, one of the Six Canonical Hadith Collections.", + "language": "Arabic", + "isbn": "978-1-86043-013-3", + "volume": "2 volumes", + "year_of_publication": "1888", + "number_page": 900, + "publisher": "Dar Ihya al-Kutub al-Arabiyah", + "rate": 4.75, + "authors": ["Imam Ibn Majah"], + "image_order": 5, + "attributes": { + "Collection Type": "Sunan (Practice)", + "Number of Hadith": "4,341", + "Number of Books": "32", + "Notable Content": "Includes rare narrations", + "Authenticity Grade": "Mixed - requires verification", + } + }, + ] + + books = {} + for book_data in books_data: + # Extract author names + author_names = book_data.pop('authors', []) + image_order = book_data.pop('image_order', 1) + attributes_dict = book_data.pop('attributes', {}) + + # Create or get the book + book, created = BookReference.objects.get_or_create( + title=book_data['title'], + defaults=book_data + ) + + if created: + self.stdout.write(self.style.SUCCESS(f'Created book: {book.title}')) + else: + # Update existing book + for key, value in book_data.items(): + setattr(book, key, value) + book.save() + self.stdout.write(self.style.WARNING(f'Updated book: {book.title}')) + + books[book.title] = book + + # Add authors to book + for author_name in author_names: + author = authors.get(author_name) + if author: + book.authors.add(author) + + # Add book image + image_path = self._get_image_path(image_order) + if image_path and os.path.exists(image_path): + # Check if image already exists for this book + if not book.images.exists(): + with open(image_path, 'rb') as img_file: + image_name = f'book{image_order}.png' + book_image = BookReferenceImage.objects.create( + book_reference=book, + order=1, + description=f"Cover image for {book.title}" + ) + book_image.image.save( + image_name, + ContentFile(img_file.read()), + save=True + ) + self.stdout.write( + self.style.SUCCESS(f'Added image to: {book.title}') + ) + else: + self.stdout.write( + self.style.WARNING( + f'Image not found at {image_path} for {book.title}' + ) + ) + + # Add attributes + for attr_title, attr_value in attributes_dict.items(): + attribute, created = BookAttribute.objects.get_or_create( + book_reference=book, + title=attr_title, + defaults={'value': attr_value} + ) + if created: + self.stdout.write( + self.style.SUCCESS( + f'Added attribute: {attr_title} to {book.title}' + ) + ) + + self.stdout.write( + self.style.SUCCESS( + f'\n✓ Successfully seeded {len(books)} books with all relations!' + ) + ) + self._print_summary() + + def _get_image_path(self, book_number): + """ + Find the image file for the given book number. + Checks multiple possible locations. + """ + possible_paths = [ + Path('seeds/images') / f'book{book_number}.png', + Path('seed_data/images') / f'book{book_number}.png', + Path('static/images') / f'book{book_number}.png', + Path('.') / 'seeds' / 'images' / f'book{book_number}.png', + ] + + for path in possible_paths: + if path.exists(): + return path + + return None + + def _print_summary(self): + """Print a summary of created data""" + self.stdout.write("\n" + "="*60) + self.stdout.write(self.style.SUCCESS("DATABASE SUMMARY")) + self.stdout.write("="*60) + + books_count = BookReference.objects.count() + authors_count = BookAuthor.objects.count() + images_count = BookReferenceImage.objects.count() + attributes_count = BookAttribute.objects.count() + + self.stdout.write(f"📚 Total Books: {books_count}") + self.stdout.write(f"✍️ Total Authors: {authors_count}") + self.stdout.write(f"🖼️ Total Images: {images_count}") + self.stdout.write(f"🏷️ Total Attributes: {attributes_count}") + self.stdout.write("="*60 + "\n") \ No newline at end of file diff --git a/apps/hadis/management/commands/seed_category_data.py b/apps/hadis/management/commands/seed_category_data.py new file mode 100644 index 0000000..19dab69 --- /dev/null +++ b/apps/hadis/management/commands/seed_category_data.py @@ -0,0 +1,497 @@ +""" +Django management command to seed mock HadisCategory trees and new Hadis +for history, fatwa and quote sources. + +Place this file in: hadis/management/commands/seed_categories.py + +Usage: + python manage.py seed_categories + python manage.py seed_categories --clear +""" + +from django.core.management.base import BaseCommand +from django.utils.text import slugify +from django.conf import settings + +from apps.hadis.models.category import HadisCategory, HadisSect +from apps.hadis.models.hadis import Hadis, HadisStatus, HadisTag + + +class Command(BaseCommand): + help = "Seed HadisCategory trees (history, fatwa, quote) and new Hadis connected to them." + + def add_arguments(self, parser): + parser.add_argument( + '--clear', + action='store_true', + help='Clear ONLY categories & hadises created by this command (history/fatwa/quote).', + ) + + def handle(self, *args, **options): + if options['clear']: + self._clear_seeded_data() + + # Ensure sects exist + try: + shia_sect = HadisSect.objects.get(sect_type=HadisSect.SectType.SHIA) + except HadisSect.DoesNotExist: + shia_sect = HadisSect.objects.create( + sect_type=HadisSect.SectType.SHIA, + title="Shia", + description="Default Shia sect" + ) + + try: + sunni_sect = HadisSect.objects.get(sect_type=HadisSect.SectType.SUNNI) + except HadisSect.DoesNotExist: + sunni_sect = HadisSect.objects.create( + sect_type=HadisSect.SectType.SUNNI, + title="Sunni", + description="Default Sunni sect" + ) + + # Optional: ensure a couple of HadisStatus entries exist + default_status, _ = HadisStatus.objects.get_or_create( + title="Authentic / Accepted", + defaults={"color": HadisStatus.ColorChoices.GREEN, "order": 1}, + ) + weak_status, _ = HadisStatus.objects.get_or_create( + title="Weak / Needs Review", + defaults={"color": HadisStatus.ColorChoices.YELLOW, "order": 2}, + ) + + # Ensure some tags exist + tags = self._ensure_tags() + + # 1) Seed HISTORY categories & hadises + self.stdout.write(self.style.SUCCESS("\n📚 Creating HISTORY categories and hadiths...")) + self._seed_history_tree(sunni_sect, default_status, tags) + + # 2) Seed FATWA categories & hadises + self.stdout.write(self.style.SUCCESS("\n📜 Creating FATWA categories and hadiths...")) + self._seed_fatwa_tree(sunni_sect, default_status, weak_status, tags) + + # 3) Seed QUOTE categories & hadises + self.stdout.write(self.style.SUCCESS("\n💬 Creating QUOTE categories and hadiths...")) + self._seed_quote_tree(shia_sect, default_status, tags) + + self._print_summary() + + # ------------------------------------------------------------------ # + # Helpers + # ------------------------------------------------------------------ # + + def _clear_seeded_data(self): + """ + Clear only categories with source_type in (history, fatwa, quote) + and hadises that are attached to those categories. + """ + self.stdout.write(self.style.WARNING("Clearing previously seeded history/fatwa/quote data...")) + leaf_categories = HadisCategory.objects.filter( + source_type__in=[ + HadisCategory.SourceType.HISTORY, + HadisCategory.SourceType.FATWA, + HadisCategory.SourceType.QUOTE, + ] + ) + Hadis.objects.filter(category__in=leaf_categories).delete() + # Delete categories (MPTT will handle tree structure) + HadisCategory.objects.filter( + source_type__in=[ + HadisCategory.SourceType.HISTORY, + HadisCategory.SourceType.FATWA, + HadisCategory.SourceType.QUOTE, + ] + ).delete() + self.stdout.write(self.style.SUCCESS("✓ Cleared seeded history/fatwa/quote categories and hadiths.")) + + def _ensure_tags(self): + base_titles = [ + "history", + "biography", + "battle", + "ethics", + "jurisprudence", + "family", + "wisdom", + "short quote", + ] + tags = [] + for title in base_titles: + tag, _ = HadisTag.objects.get_or_create(title=title) + tags.append(tag) + return tags + + # ---------------- HISTORY ---------------- # + + def _seed_history_tree(self, sect, default_status, tags): + """ + Create a small HISTORY tree: + History of Islam + ├─ Early Caliphate (leaf) + └─ Battles (leaf) + And add several hadith-like historical reports. + """ + root, _ = HadisCategory.objects.get_or_create( + sect=sect, + source_type=HadisCategory.SourceType.HISTORY, + title="History of Islam", + defaults={ + "description": "High-level historical themes related to early Islamic history.", + "order": 1, + }, + ) + + early_caliphate, _ = HadisCategory.objects.get_or_create( + sect=sect, + source_type=HadisCategory.SourceType.HISTORY, + parent=root, + title="Early Caliphate", + defaults={ + "description": "Events and reports from the period of the first caliphs.", + "order": 1, + }, + ) + + battles, _ = HadisCategory.objects.get_or_create( + sect=sect, + source_type=HadisCategory.SourceType.HISTORY, + parent=root, + title="Battles and Expeditions", + defaults={ + "description": "Key battles and expeditions in early Islamic history.", + "order": 2, + }, + ) + + # Create some historical “hadith” entries (reports) + # For simplicity, use new numbers starting from 1900+ + self._create_hadis( + number=1900, + category=early_caliphate, + title="The Consultation of the Companions", + text=( + "It is reported in historical works that the companions would gather and " + "consult one another regarding major affairs of the community." + ), + translation_en=( + "Historical reports mention that the companions would consult one another " + "on major communal matters." + ), + status=default_status, + tags=[t for t in tags if t.title in ["history", "biography"]], + ) + + self._create_hadis( + number=1901, + category=early_caliphate, + title="Establishment of the Public Treasury", + text=( + "Some historians narrate that during the early caliphate a public treasury " + "was organized to administer charity and public funds." + ), + translation_en=( + "Historical sources state that a public treasury was set up to manage " + "charity and communal funds." + ), + status=default_status, + tags=[t for t in tags if t.title in ["history", "jurisprudence"]], + ) + + self._create_hadis( + number=1910, + category=battles, + title="Report of the Battle Preparations", + text=( + "Chronicles record that the believers prepared carefully before major battles, " + "ensuring justice and discipline in their ranks." + ), + translation_en=( + "Historical chronicles record careful preparations and discipline before major battles." + ), + status=default_status, + tags=[t for t in tags if t.title in ["history", "battle"]], + ) + + self._create_hadis( + number=1911, + category=battles, + title="Mercy Shown After Victory", + text=( + "Historical narrations mention that after some victories, clemency and mercy were " + "shown to prisoners and civilians." + ), + translation_en=( + "Historical narrations mention mercy and clemency after some military victories." + ), + status=default_status, + tags=[t for t in tags if t.title in ["history", "ethics"]], + ) + + # ---------------- FATWA ---------------- # + + def _seed_fatwa_tree(self, sect, default_status, weak_status, tags): + """ + Create a FATWA tree like: + Contemporary Fatwas + ├─ Worship (leaf) + └─ Family Issues (leaf) + Plus a second root: + Financial Fatwas + └─ Trade and Contracts (leaf) + """ + root_contemporary, _ = HadisCategory.objects.get_or_create( + sect=sect, + source_type=HadisCategory.SourceType.FATWA, + title="Contemporary Fatwas", + defaults={ + "description": "Modern juristic responses to contemporary questions.", + "order": 1, + }, + ) + + worship, _ = HadisCategory.objects.get_or_create( + sect=sect, + source_type=HadisCategory.SourceType.FATWA, + parent=root_contemporary, + title="Worship and Rituals", + defaults={ + "description": "Fatwas about prayer, fasting and other acts of worship.", + "order": 1, + }, + ) + + family_issues, _ = HadisCategory.objects.get_or_create( + sect=sect, + source_type=HadisCategory.SourceType.FATWA, + parent=root_contemporary, + title="Family Issues", + defaults={ + "description": "Fatwas regarding marriage, divorce and family obligations.", + "order": 2, + }, + ) + + financial_root, _ = HadisCategory.objects.get_or_create( + sect=sect, + source_type=HadisCategory.SourceType.FATWA, + title="Financial Fatwas", + defaults={ + "description": "Juristic rulings about trade, contracts and modern finance.", + "order": 2, + }, + ) + + trade_contracts, _ = HadisCategory.objects.get_or_create( + sect=sect, + source_type=HadisCategory.SourceType.FATWA, + parent=financial_root, + title="Trade and Contracts", + defaults={ + "description": "Fatwas related to buying, selling and contractual agreements.", + "order": 1, + }, + ) + + # Create some “fatwa-style” hadith entries (answers / rulings) + self._create_hadis( + number=1920, + category=worship, + title="Fatwa on Combining Prayers While Traveling", + text=( + "A contemporary juristic council has ruled that combining prayers while traveling " + "is permitted when hardship is present, following classical precedents." + ), + translation_en=( + "A modern fatwa allows combining prayers during travel where hardship exists, " + "based on earlier jurisprudence." + ), + status=default_status, + tags=[t for t in tags if t.title in ["jurisprudence", "ethics"]], + ) + + self._create_hadis( + number=1921, + category=worship, + title="Fatwa on Using Local Calculations for Prayer Times", + text=( + "Modern scholars have issued fatwas permitting the use of accurate astronomical " + "calculations for determining prayer times." + ), + translation_en=( + "Contemporary fatwas permit using precise astronomical calculations for prayer times." + ), + status=weak_status, + tags=[t for t in tags if t.title in ["jurisprudence", "knowledge"]], + ) + + self._create_hadis( + number=1930, + category=family_issues, + title="Fatwa on Upholding Family Ties", + text=( + "A fatwa committee emphasized that maintaining family ties is obligatory and that " + "cutting off relatives without valid reason is sinful." + ), + translation_en=( + "A fatwa stresses that keeping family ties is obligatory and severing them without cause is sinful." + ), + status=default_status, + tags=[t for t in tags if t.title in ["family", "ethics"]], + ) + + self._create_hadis( + number=1940, + category=trade_contracts, + title="Fatwa on Transparent Business Contracts", + text=( + "Scholars have ruled that contracts must be transparent and free from deception in order " + "to be valid in Islamic law." + ), + translation_en=( + "A modern fatwa requires transparency and absence of deception in business contracts." + ), + status=default_status, + tags=[t for t in tags if t.title in ["business", "jurisprudence"]] if any( + t.title == "business" for t in tags + ) else [t for t in tags if t.title in ["jurisprudence"]], + ) + + # ---------------- QUOTE ---------------- # + + def _seed_quote_tree(self, sect, default_status, tags): + """ + Create a QUOTE tree: + Wisdom Quotes + ├─ Short Wisdom (leaf) + └─ On Knowledge (leaf) + """ + root, _ = HadisCategory.objects.get_or_create( + sect=sect, + source_type=HadisCategory.SourceType.QUOTE, + title="Wisdom Quotes", + defaults={ + "description": "Short wise sayings and inspirational quotes.", + "order": 1, + }, + ) + + short_wisdom, _ = HadisCategory.objects.get_or_create( + sect=sect, + source_type=HadisCategory.SourceType.QUOTE, + parent=root, + title="Short Wisdom", + defaults={ + "description": "Very short, memorable quotes on character and behavior.", + "order": 1, + }, + ) + + on_knowledge, _ = HadisCategory.objects.get_or_create( + sect=sect, + source_type=HadisCategory.SourceType.QUOTE, + parent=root, + title="On Knowledge", + defaults={ + "description": "Quotes emphasizing the virtue of knowledge and learning.", + "order": 2, + }, + ) + + # Short quote-style entries + self._create_hadis( + number=1950, + category=short_wisdom, + title="The Measure of a Heart", + text="It is said: The worth of a person is in what their heart carries of mercy and truth.", + translation_en="It is said: A person’s value is measured by the mercy and truth in their heart.", + status=default_status, + tags=[t for t in tags if t.title in ["wisdom", "short quote", "ethics"]], + ) + + self._create_hadis( + number=1951, + category=short_wisdom, + title="Silence and Wisdom", + text="One of the wise said: Many people would be considered wise if they knew when to remain silent.", + translation_en="A wise saying: Many would be counted wise if they knew when to be silent.", + status=default_status, + tags=[t for t in tags if t.title in ["wisdom", "short quote"]], + ) + + self._create_hadis( + number=1960, + category=on_knowledge, + title="Seeking Knowledge as Light", + text="It is narrated from the scholars: Knowledge is a light that guides the heart towards what benefits it.", + translation_en="Scholars say: Knowledge is a light guiding the heart to what benefits it.", + status=default_status, + tags=[t for t in tags if t.title in ["knowledge", "wisdom"]], + ) + + self._create_hadis( + number=1961, + category=on_knowledge, + title="Learning until the End", + text="One sage said: Continue to seek knowledge until the last day of your life, for ignorance is a darkness.", + translation_en="A sage said: Seek knowledge until your last day, for ignorance is darkness.", + status=default_status, + tags=[t for t in tags if t.title in ["knowledge", "wisdom"]], + ) + + # ---------------- utility to create Hadis ---------------- # + + def _create_hadis(self, number, category, title, text, translation_en, status, tags): + """ + Create or update a Hadis with the given number and category. + Translation uses {'en': '...'} structure as requested. + """ + hadis, created = Hadis.objects.get_or_create( + number=number, + category=category, + defaults={ + "title": title, + "title_narrator": None, + "description": "", + "text": text, + "translation": {"en": translation_en}, + "status": True, + "hadis_status": status, + "hadis_status_text": status.title if status else "", + "address": "", + "links": {}, + "explanation": "", + }, + ) + if not created: + hadis.title = title + hadis.text = text + hadis.translation = {"en": translation_en} + hadis.hadis_status = status + hadis.hadis_status_text = status.title if status else "" + hadis.category = category + hadis.save() + + if tags: + hadis.tags.set(tags) + return hadis + + def _print_summary(self): + from apps.hadis.models import HadisCategory, Hadis + + self.stdout.write("\n" + "=" * 70) + self.stdout.write(self.style.SUCCESS("CATEGORY & HADIS SUMMARY")) + self.stdout.write("=" * 70) + + history_count = HadisCategory.objects.filter(source_type=HadisCategory.SourceType.HISTORY).count() + fatwa_count = HadisCategory.objects.filter(source_type=HadisCategory.SourceType.FATWA).count() + quote_count = HadisCategory.objects.filter(source_type=HadisCategory.SourceType.QUOTE).count() + + history_hadis = Hadis.objects.filter(category__source_type=HadisCategory.SourceType.HISTORY).count() + fatwa_hadis = Hadis.objects.filter(category__source_type=HadisCategory.SourceType.FATWA).count() + quote_hadis = Hadis.objects.filter(category__source_type=HadisCategory.SourceType.QUOTE).count() + + self.stdout.write(f"📂 HISTORY categories: {history_count} | hadith-like records: {history_hadis}") + self.stdout.write(f"📂 FATWA categories: {fatwa_count} | fatwa records: {fatwa_hadis}") + self.stdout.write(f"📂 QUOTE categories: {quote_count} | quote records: {quote_hadis}") + self.stdout.write("=" * 70 + "\n") diff --git a/apps/hadis/management/commands/seed_hadis_2.py b/apps/hadis/management/commands/seed_hadis_2.py new file mode 100644 index 0000000..8341218 --- /dev/null +++ b/apps/hadis/management/commands/seed_hadis_2.py @@ -0,0 +1,432 @@ +""" +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") \ No newline at end of file diff --git a/apps/hadis/management/commands/seed_transmitters.py b/apps/hadis/management/commands/seed_transmitters.py new file mode 100644 index 0000000..5ae9cef --- /dev/null +++ b/apps/hadis/management/commands/seed_transmitters.py @@ -0,0 +1,613 @@ +""" +Django management command to seed mock data for hadith transmitters and related models. +Place this file in: yourapp/management/commands/seed_transmitters.py + +Usage: python manage.py seed_transmitters + python manage.py seed_transmitters --clear +""" + +import json +from django.core.management.base import BaseCommand +from django.utils.text import slugify +from apps.hadis.models.transmitter import ( + NarratorLayer, + Transmitters, + HadisTransmitter, + TransmitterOpinion, + TransmitterOriginalText +) + + +class Command(BaseCommand): + help = 'Seed the database with mock hadith transmitter 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 transmitter data...')) + TransmitterOriginalText.objects.all().delete() + TransmitterOpinion.objects.all().delete() + HadisTransmitter.objects.all().delete() + Transmitters.objects.all().delete() + NarratorLayer.objects.all().delete() + self.stdout.write(self.style.SUCCESS('Data cleared successfully!')) + + # Step 1: Create Narrator Layers (Tabaqat) + self.stdout.write(self.style.SUCCESS('\n📚 Creating Narrator Layers...')) + layers_data = [ + { + "name": "Sahaba (Companions)", + "number": 1, + "description": "The companions of Prophet Muhammad (PBUH) who heard directly from him." + }, + { + "name": "Tabi'un (Successors)", + "number": 2, + "description": "Narrators who lived after the Prophet's era and heard from the companions." + }, + { + "name": "Taba' Tabi'in (Followers of Successors)", + "number": 3, + "description": "Narrators who heard from the Successors." + }, + { + "name": "Later Generations", + "number": 4, + "description": "Narrators from later Islamic centuries, known for their scholarship." + }, + { + "name": "Modern Era Scholars", + "number": 5, + "description": "Contemporary scholars who have specialized knowledge of hadith narration." + }, + ] + + layers = {} + for layer_data in layers_data: + layer, created = NarratorLayer.objects.get_or_create( + number=layer_data['number'], + defaults={ + 'name': layer_data['name'], + 'description': layer_data['description'], + 'slug': slugify(layer_data['name']) + } + ) + layers[layer_data['number']] = layer + status = '✓ Created' if created else '• Updated' + self.stdout.write(f"{status}: {layer.name} (Layer {layer.number})") + + # Step 2: Create Transmitters (Hadith Narrators) + self.stdout.write(self.style.SUCCESS('\n👥 Creating Transmitters...')) + transmitters_data = [ + { + "full_name": "Abu Hurayrah", + "kunya": "Abu Hurayrah", + "known_as": "Abd al-Rahman ibn Sakhr", + "nickname": "Father of the Kitten", + "origin": "Yamama, Arabia", + "lived_in": "Medina, Syria", + "died_in": "Medina", + "birth_year_hijri": 7, + "death_year_hijri": 58, + "age_at_death": 78, + "generation": 1, + "reliability": "very_reliable", + "madhhab": "sunni", + "in_sahih_muslim": True, + "in_sahih_bukhari": True, + "description": "One of the most prolific hadith narrators, reported 5,374 ahadith.", + "narrator_layer": 1, + }, + { + "full_name": "Aisha bint Abu Bakr", + "kunya": "Umm al-Mu'minin", + "known_as": "Mother of the Believers", + "nickname": "Al-Siddiqa", + "origin": "Medina", + "lived_in": "Medina", + "died_in": "Medina", + "birth_year_hijri": None, + "death_year_hijri": 58, + "age_at_death": 66, + "generation": 1, + "reliability": "very_reliable", + "madhhab": "sunni", + "in_sahih_muslim": True, + "in_sahih_bukhari": True, + "description": "Wife of the Prophet Muhammad (PBUH), a major source of hadith about daily life.", + "narrator_layer": 1, + }, + { + "full_name": "Jabir ibn Abdullah al-Ansari", + "kunya": "Abu Abdullah", + "known_as": "Jabir", + "nickname": "Al-Ansari", + "origin": "Medina", + "lived_in": "Medina", + "died_in": "Medina", + "birth_year_hijri": 10, + "death_year_hijri": 74, + "age_at_death": 94, + "generation": 1, + "reliability": "very_reliable", + "madhhab": "sunni", + "in_sahih_muslim": True, + "in_sahih_bukhari": True, + "description": "One of the long-lived companions, reported numerous ahadith on various topics.", + "narrator_layer": 1, + }, + { + "full_name": "Imam Malik ibn Anas", + "kunya": "Abu Abdullah", + "known_as": "Malik", + "nickname": "Imam of Imams", + "origin": "Medina", + "lived_in": "Medina", + "died_in": "Medina", + "birth_year_hijri": 93, + "death_year_hijri": 179, + "age_at_death": 86, + "generation": 3, + "reliability": "very_reliable", + "madhhab": "maliki", + "in_sahih_muslim": True, + "in_sahih_bukhari": True, + "description": "Founder of the Maliki school of Islamic jurisprudence, compiler of Al-Muwatta.", + "narrator_layer": 3, + }, + { + "full_name": "Al-Qasim ibn Muhammad", + "kunya": "Abu Muhammad", + "known_as": "Al-Qasim", + "nickname": "Son of the Rightly Guided", + "origin": "Medina", + "lived_in": "Medina", + "died_in": "Medina", + "birth_year_hijri": 38, + "death_year_hijri": 106, + "age_at_death": 68, + "generation": 2, + "reliability": "reliable", + "madhhab": "sunni", + "in_sahih_muslim": True, + "in_sahih_bukhari": True, + "description": "Son of Amir al-Mu'minin, known for his knowledge of Islamic jurisprudence.", + "narrator_layer": 2, + }, + { + "full_name": "Urwa ibn al-Zubayr", + "kunya": "Abu Abdullah", + "known_as": "Urwa", + "nickname": "The Jurist", + "origin": "Medina", + "lived_in": "Medina, Mecca", + "died_in": "Medina", + "birth_year_hijri": 23, + "death_year_hijri": 94, + "age_at_death": 71, + "generation": 2, + "reliability": "very_reliable", + "madhhab": "sunni", + "in_sahih_muslim": True, + "in_sahih_bukhari": True, + "description": "Prominent Tabi'un scholar and transmitter of hadith from Aisha.", + "narrator_layer": 2, + }, + { + "full_name": "Abdullah ibn Abbas", + "kunya": "Abu Abbas", + "known_as": "Ibn Abbas", + "nickname": "Hibr al-Ummah (The Learned Scholar of the Nation)", + "origin": "Medina", + "lived_in": "Medina, Mecca, Basra", + "died_in": "Taif", + "birth_year_hijri": 3, + "death_year_hijri": 68, + "age_at_death": 71, + "generation": 1, + "reliability": "very_reliable", + "madhhab": "sunni", + "in_sahih_muslim": True, + "in_sahih_bukhari": True, + "description": "Cousin of the Prophet (PBUH), famous for Quranic exegesis and hadith knowledge.", + "narrator_layer": 1, + }, + { + "full_name": "Nafi' (Mawla of Ibn Umar)", + "kunya": "Abu Abdullah", + "known_as": "Nafi'", + "nickname": "The Freed Slave", + "origin": "Ethiopia", + "lived_in": "Medina", + "died_in": "Medina", + "birth_year_hijri": 25, + "death_year_hijri": 117, + "age_at_death": 92, + "generation": 2, + "reliability": "very_reliable", + "madhhab": "sunni", + "in_sahih_muslim": True, + "in_sahih_bukhari": True, + "description": "Freed slave of Abdullah ibn Umar, transmitted numerous hadith from him.", + "narrator_layer": 2, + }, + { + "full_name": "Imam Ahmad ibn Hanbal", + "kunya": "Abu Abdullah", + "known_as": "Ahmad", + "nickname": "Shaykh al-Islam", + "origin": "Khorasan", + "lived_in": "Baghdad", + "died_in": "Baghdad", + "birth_year_hijri": 164, + "death_year_hijri": 241, + "age_at_death": 77, + "generation": 4, + "reliability": "very_reliable", + "madhhab": "hanbali", + "in_sahih_muslim": False, + "in_sahih_bukhari": False, + "description": "Founder of the Hanbali school, compiler of Musnad Ahmad with 40,000+ hadith.", + "narrator_layer": 3, + }, + { + "full_name": "Sufyan ibn Uyayna", + "kunya": "Abu Muhammad", + "known_as": "Sufyan", + "nickname": "Amir al-Mu'minin fil-Hadith", + "origin": "Kufa", + "lived_in": "Mecca, Kufa", + "died_in": "Mecca", + "birth_year_hijri": 107, + "death_year_hijri": 198, + "age_at_death": 91, + "generation": 3, + "reliability": "very_reliable", + "madhhab": "shafii", + "in_sahih_muslim": True, + "in_sahih_bukhari": True, + "description": "Great hadith scholar and judge, known for his exceptional memory.", + "narrator_layer": 3, + }, + ] + + transmitters = {} + for trans_data in transmitters_data: + narrator_layer_num = trans_data.pop('narrator_layer') + narrator_layer = layers.get(narrator_layer_num) + + transmitter, created = Transmitters.objects.get_or_create( + full_name=trans_data['full_name'], + defaults=trans_data + ) + transmitters[trans_data['full_name']] = transmitter + status = '✓ Created' if created else '• Updated' + self.stdout.write(f"{status}: {transmitter.full_name}") + + # Step 3: Create Transmitter Opinions + self.stdout.write(self.style.SUCCESS('\n💬 Creating Transmitter Opinions...')) + opinions_data = [ + { + "transmitter_name": "Abu Hurayrah", + "scholar_name": "Imam al-Bukhari", + "opinion_text": "Abu Hurayrah is one of the most reliable narrators with a perfect memory and integrity.", + "status": "confirmed" + }, + { + "transmitter_name": "Abu Hurayrah", + "scholar_name": "Imam Muslim", + "opinion_text": "His narrations are authentic and widely accepted in the Islamic jurisprudence.", + "status": "confirmed" + }, + { + "transmitter_name": "Aisha bint Abu Bakr", + "scholar_name": "Imam al-Bukhari", + "opinion_text": "The Mother of the Believers is the most reliable source for hadith about the Prophet's household.", + "status": "confirmed" + }, + { + "transmitter_name": "Jabir ibn Abdullah al-Ansari", + "scholar_name": "Ibn Hajar al-Asqalani", + "opinion_text": "His longevity allowed him to transmit from many companions and successors.", + "status": "confirmed" + }, + { + "transmitter_name": "Imam Malik ibn Anas", + "scholar_name": "Imam ash-Shafi'i", + "opinion_text": "Malik is among the most knowledgeable of the Medinese scholars in jurisprudence.", + "status": "confirmed" + }, + { + "transmitter_name": "Imam Malik ibn Anas", + "scholar_name": "Imam Ahmad ibn Hanbal", + "opinion_text": "Malik's narrations form the basis of sound Islamic jurisprudence.", + "status": "confirmed" + }, + { + "transmitter_name": "Al-Qasim ibn Muhammad", + "scholar_name": "Ibn Hajar al-Asqalani", + "opinion_text": "Al-Qasim is a trustworthy narrator from the Tabi'un generation with reliable traditions.", + "status": "confirmed" + }, + { + "transmitter_name": "Urwa ibn al-Zubayr", + "scholar_name": "Imam al-Bukhari", + "opinion_text": "Urwa is among the most knowledgeable about the traditions of the Prophet's household.", + "status": "confirmed" + }, + { + "transmitter_name": "Abdullah ibn Abbas", + "scholar_name": "Imam at-Tirmidhi", + "opinion_text": "Ibn Abbas has exceptional knowledge in Quranic interpretation and hadith narration.", + "status": "confirmed" + }, + { + "transmitter_name": "Nafi' (Mawla of Ibn Umar)", + "scholar_name": "Imam Muslim", + "opinion_text": "Nafi' is one of the most reliable freed slaves who transmitted authentic traditions.", + "status": "confirmed" + }, + { + "transmitter_name": "Imam Ahmad ibn Hanbal", + "scholar_name": "Ibn Hajar al-Asqalani", + "opinion_text": "Ahmad ibn Hanbal's knowledge of hadith is unparalleled in his era.", + "status": "confirmed" + }, + { + "transmitter_name": "Sufyan ibn Uyayna", + "scholar_name": "Imam al-Bukhari", + "opinion_text": "Sufyan is a highly reliable hadith scholar with exceptional memory.", + "status": "confirmed" + }, + ] + + for opinion_data in opinions_data: + transmitter_name = opinion_data.pop('transmitter_name') + transmitter = transmitters.get(transmitter_name) + if transmitter: + opinion, created = TransmitterOpinion.objects.get_or_create( + transmitter=transmitter, + scholar_name=opinion_data['scholar_name'], + defaults=opinion_data + ) + if created: + self.stdout.write( + self.style.SUCCESS( + f"✓ Opinion added: {opinion_data['scholar_name']} on {transmitter_name}" + ) + ) + + # Step 4: Create Original Texts + self.stdout.write(self.style.SUCCESS('\n📜 Creating Transmitter Original Texts...')) + original_texts_data = [ + { + "transmitter_name": "Abu Hurayrah", + "title": "His Narration on Zakat", + "text": "حدثنا أبو هريرة قال: قال رسول الله صلى الله عليه وسلم: من آمن بالله واليوم الآخر فليؤد الزكاة", + "translation": [ + {"language_code": "en", "text": "Abu Hurayrah narrated: The Messenger of Allah (PBUH) said: Whoever believes in Allah and the Last Day, let him pay the Zakat (alms)."}, + {"language_code": "ar", "text": "أبو هريرة: من آمن بالله واليوم الآخر فليؤد الزكاة"} + ], + "share_link": "https://hadith.example.com/abu-hurayrah/zakat-1" + }, + { + "transmitter_name": "Aisha bint Abu Bakr", + "title": "Her Account of the Prophet's Night Prayer", + "text": "قالت عائشة: كان النبي صلى الله عليه وسلم يقوم الليل فيصلي ثلاث عشرة ركعة", + "translation": [ + {"language_code": "en", "text": "Aisha said: The Prophet (PBUH) used to pray at night thirteen rak'ahs."}, + {"language_code": "ar", "text": "عائشة: كان النبي يقوم الليل بثلاث عشرة ركعة"} + ], + "share_link": "https://hadith.example.com/aisha/night-prayer-1" + }, + { + "transmitter_name": "Jabir ibn Abdullah al-Ansari", + "title": "The Farewell Hajj Narration", + "text": "قال جابر: خرجنا مع رسول الله صلى الله عليه وسلم في حجة الوداع", + "translation": [ + {"language_code": "en", "text": "Jabir narrated: We went out with the Messenger of Allah (PBUH) for the Farewell Hajj."}, + {"language_code": "ar", "text": "جابر: خرجنا مع رسول الله في حجة الوداع"} + ], + "share_link": "https://hadith.example.com/jabir/farewell-hajj-1" + }, + { + "transmitter_name": "Imam Malik ibn Anas", + "title": "Narration on Purity and Prayer", + "text": "قال مالك: الطهارة شرط من شروط الصلاة", + "translation": [ + {"language_code": "en", "text": "Malik said: Purification is a condition for the validity of prayer."}, + {"language_code": "ar", "text": "مالك: الطهارة من شروط صحة الصلاة"} + ], + "share_link": "https://hadith.example.com/malik/purity-1" + }, + { + "transmitter_name": "Abdullah ibn Abbas", + "title": "His Commentary on Divine Justice", + "text": "قال ابن عباس: إن الله تعالى عدل لا يظلم أحدا", + "translation": [ + {"language_code": "en", "text": "Ibn Abbas said: Truly Allah is Just and does not oppress anyone."}, + {"language_code": "ar", "text": "ابن عباس: الله عدل لا يظلم أحدا"} + ], + "share_link": "https://hadith.example.com/ibn-abbas/justice-1" + }, + { + "transmitter_name": "Sufyan ibn Uyayna", + "title": "Teaching on Knowledge Seeking", + "text": "قال سفيان بن عيينة: طلب العلم فريضة على كل مسلم", + "translation": [ + {"language_code": "en", "text": "Sufyan ibn Uyayna said: Seeking knowledge is an obligation for every Muslim."}, + {"language_code": "ar", "text": "سفيان: طلب العلم فريضة على كل مسلم"} + ], + "share_link": "https://hadith.example.com/sufyan/knowledge-1" + }, + ] + + for text_data in original_texts_data: + transmitter_name = text_data.pop('transmitter_name') + transmitter = transmitters.get(transmitter_name) + if transmitter: + original_text, created = TransmitterOriginalText.objects.get_or_create( + transmitter=transmitter, + title=text_data['title'], + defaults=text_data + ) + if created: + self.stdout.write( + self.style.SUCCESS( + f"✓ Original text added: {text_data['title']} by {transmitter_name}" + ) + ) + + # Step 5: Create Hadis Transmitters (Chain of narration) + self.stdout.write(self.style.SUCCESS('\n⛓️ Creating Hadis Transmitters (Chains)...')) + + # Sample hadis IDs to use (you can have any ID from 1800 to 1852) + hadis_ids = list(range(1800, 1853)) + + # Create chains for different hadis + chains_data = [ + { + "hadis_id": hadis_ids[0], + "chain": [ + {"transmitter_name": "Abu Hurayrah", "order": 1, "layer": 1, "status": "reliable"}, + {"transmitter_name": "Imam Malik ibn Anas", "order": 2, "layer": 3, "status": "reliable"}, + ] + }, + { + "hadis_id": hadis_ids[1], + "chain": [ + {"transmitter_name": "Aisha bint Abu Bakr", "order": 1, "layer": 1, "status": "reliable"}, + {"transmitter_name": "Urwa ibn al-Zubayr", "order": 2, "layer": 2, "status": "reliable"}, + {"transmitter_name": "Imam Malik ibn Anas", "order": 3, "layer": 3, "status": "reliable"}, + ] + }, + { + "hadis_id": hadis_ids[2], + "chain": [ + {"transmitter_name": "Jabir ibn Abdullah al-Ansari", "order": 1, "layer": 1, "status": "reliable"}, + {"transmitter_name": "Al-Qasim ibn Muhammad", "order": 2, "layer": 2, "status": "reliable"}, + {"transmitter_name": "Sufyan ibn Uyayna", "order": 3, "layer": 3, "status": "reliable"}, + ] + }, + { + "hadis_id": hadis_ids[3], + "chain": [ + {"transmitter_name": "Abdullah ibn Abbas", "order": 1, "layer": 1, "status": "reliable"}, + {"transmitter_name": "Nafi' (Mawla of Ibn Umar)", "order": 2, "layer": 2, "status": "reliable"}, + {"transmitter_name": "Imam Ahmad ibn Hanbal", "order": 3, "layer": 3, "status": "reliable"}, + ] + }, + { + "hadis_id": hadis_ids[4], + "chain": [ + {"transmitter_name": "Abu Hurayrah", "order": 1, "layer": 1, "status": "reliable"}, + {"transmitter_name": "Sufyan ibn Uyayna", "order": 2, "layer": 3, "status": "reliable"}, + ] + }, + { + "hadis_id": hadis_ids[5], + "chain": [ + {"transmitter_name": "Aisha bint Abu Bakr", "order": 1, "layer": 1, "status": "reliable"}, + {"transmitter_name": "Al-Qasim ibn Muhammad", "order": 2, "layer": 2, "status": "reliable"}, + ] + }, + { + "hadis_id": hadis_ids[6], + "chain": [ + {"transmitter_name": "Jabir ibn Abdullah al-Ansari", "order": 1, "layer": 1, "status": "reliable"}, + {"transmitter_name": "Nafi' (Mawla of Ibn Umar)", "order": 2, "layer": 2, "status": "reliable"}, + {"transmitter_name": "Imam Malik ibn Anas", "order": 3, "layer": 3, "status": "reliable"}, + {"transmitter_name": "Sufyan ibn Uyayna", "order": 4, "layer": 3, "status": "reliable"}, + ] + }, + { + "hadis_id": hadis_ids[7], + "chain": [ + {"transmitter_name": "Abdullah ibn Abbas", "order": 1, "layer": 1, "status": "reliable"}, + {"transmitter_name": "Urwa ibn al-Zubayr", "order": 2, "layer": 2, "status": "reliable"}, + {"transmitter_name": "Imam Ahmad ibn Hanbal", "order": 3, "layer": 3, "status": "reliable"}, + ] + }, + { + "hadis_id": hadis_ids[8], + "chain": [ + {"transmitter_name": "Abu Hurayrah", "order": 1, "layer": 1, "status": "reliable"}, + {"transmitter_name": "Al-Qasim ibn Muhammad", "order": 2, "layer": 2, "status": "reliable"}, + {"transmitter_name": "Imam Malik ibn Anas", "order": 3, "layer": 3, "status": "reliable"}, + {"transmitter_name": "Sufyan ibn Uyayna", "order": 4, "layer": 3, "status": "reliable"}, + ] + }, + { + "hadis_id": hadis_ids[9], + "chain": [ + {"transmitter_name": "Aisha bint Abu Bakr", "order": 1, "layer": 1, "status": "reliable"}, + {"transmitter_name": "Nafi' (Mawla of Ibn Umar)", "order": 2, "layer": 2, "status": "reliable"}, + ] + }, + ] + + hadis_transmitter_count = 0 + for chain_data in chains_data: + hadis_id = chain_data['hadis_id'] + chain = chain_data['chain'] + + for item in chain: + transmitter = transmitters.get(item['transmitter_name']) + layer = layers.get(item['layer']) + + if transmitter and layer: + hadis_trans, created = HadisTransmitter.objects.get_or_create( + hadis_id=hadis_id, + transmitter=transmitter, + order=item['order'], + defaults={ + 'narrator_layer': layer, + 'status': item['status'], + 'is_gap': False + } + ) + if created: + hadis_transmitter_count += 1 + self.stdout.write( + self.style.SUCCESS( + f"✓ Chain link: Hadis {hadis_id} <- {item['transmitter_name']} (Order {item['order']})" + ) + ) + + self.stdout.write( + self.style.SUCCESS( + f'\n✓ Successfully seeded transmitter data!' + ) + ) + self._print_summary(transmitters, hadis_transmitter_count) + + def _print_summary(self, transmitters, hadis_transmitter_count): + """Print a summary of created data""" + self.stdout.write("\n" + "="*70) + self.stdout.write(self.style.SUCCESS("TRANSMITTER DATABASE SUMMARY")) + self.stdout.write("="*70) + + layers_count = NarratorLayer.objects.count() + transmitters_count = Transmitters.objects.count() + opinions_count = TransmitterOpinion.objects.count() + original_texts_count = TransmitterOriginalText.objects.count() + + self.stdout.write(f"📚 Narrator Layers: {layers_count}") + self.stdout.write(f"👥 Total Transmitters: {transmitters_count}") + self.stdout.write(f"💬 Transmitter Opinions: {opinions_count}") + self.stdout.write(f"📜 Original Texts: {original_texts_count}") + self.stdout.write(f"⛓️ Hadis Transmitter Chains: {hadis_transmitter_count}") + + self.stdout.write("\n" + "="*70) + self.stdout.write(self.style.WARNING("Notable Transmitters Created:")) + self.stdout.write("="*70) + for name in list(transmitters.keys())[:5]: + self.stdout.write(f" • {name}") + self.stdout.write(f" ... and {max(0, len(transmitters) - 5)} more") + self.stdout.write("="*70 + "\n") \ No newline at end of file diff --git a/apps/hadis/serializers/hadis.py b/apps/hadis/serializers/hadis.py index c1d7ee6..d32969d 100644 --- a/apps/hadis/serializers/hadis.py +++ b/apps/hadis/serializers/hadis.py @@ -47,15 +47,16 @@ class HadisSyncSerializer(serializers.ModelSerializer): def get_translations(self, obj): """Get all translations as {lang: text}""" - translations_dict = {} - if obj.translation and isinstance(obj.translation, list): - for tr in obj.translation: - if isinstance(tr, dict): - lang_code = tr.get('language_code') - title = tr.get('title') - if lang_code: - translations_dict[lang_code] = title - return translations_dict + # translations_dict = {} + # if obj.translation and isinstance(obj.translation, list): + # for tr in obj.translation: + # if isinstance(tr, dict): + # lang_code = tr.get('language_code') + # title = tr.get('title') + # if lang_code: + # translations_dict[lang_code] = title + # return translations_dict + return obj.translation def get_detail(self, obj): """Detail group: address, status, share, links, tags, references, reference_images""" @@ -170,7 +171,7 @@ class HadisListSerializer(serializers.ModelSerializer): """Get translation based on request language""" request = self.context.get('request') language_code = getattr(request, 'LANGUAGE_CODE', 'en') - return obj.get_translation(language_code) + return obj.translation.get(language_code) class HadisStatusSerializer(serializers.ModelSerializer): @@ -213,7 +214,7 @@ class TransmitterOpinionSerializer(serializers.ModelSerializer): class Meta: model = TransmitterOpinion - fields = '__all__' + fields = ['id','transmitter','scholar_name','opinion_text','status'] class TransmitterOriginalTextSerializer(serializers.ModelSerializer): """ Serializer for TransmitterOriginalText """ @@ -418,7 +419,7 @@ class HadisCorrectionSerializer(serializers.ModelSerializer): """Get translation based on request language""" request = self.context.get('request') language_code = getattr(request, 'LANGUAGE_CODE', 'en') - return obj.translation.get(language_code, '') + return obj.translation.get(language_code) class HadisBasicSerializer(serializers.ModelSerializer): @@ -437,7 +438,7 @@ class HadisBasicSerializer(serializers.ModelSerializer): """Get translation based on request language""" request = self.context.get('request') language_code = getattr(request, 'LANGUAGE_CODE', 'en') - return obj.get_translation(language_code) + return obj.translation.get(language_code) def get_category(self, obj): """Get category id and title""" if obj.category: @@ -492,4 +493,4 @@ class HadisDetailSerializer(serializers.ModelSerializer): """Get translation based on request language""" request = self.context.get('request') language_code = getattr(request, 'LANGUAGE_CODE', 'en') - return obj.get_translation(language_code) + return obj.translation.get(language_code) diff --git a/apps/hadis/views/hadis.py b/apps/hadis/views/hadis.py index a123c9a..00c8dbf 100644 --- a/apps/hadis/views/hadis.py +++ b/apps/hadis/views/hadis.py @@ -36,8 +36,8 @@ class HadisSyncView(ListAPIView): ).prefetch_related( 'tags', 'transmitters__transmitter', - 'references__book_reference__images', - 'references__book_reference__authors', + 'references__images', + 'references__book_reference', 'hadiscorrection_set' ).order_by('id') diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/seed_books.py b/scripts/seed_books.py new file mode 100644 index 0000000..a321a3c --- /dev/null +++ b/scripts/seed_books.py @@ -0,0 +1,276 @@ +""" +Django management command to seed mock data for hadith book references. +Place this file in: yourapp/management/commands/seed_books.py + +Usage: python manage.py seed_books +""" + +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 apps.hadis.models.reference import ( + BookReference, + BookReferenceImage, + BookAuthor, + BookAttribute +) + + +class Command(BaseCommand): + help = 'Seed the database with mock hadith book 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 data...')) + BookAttribute.objects.all().delete() + BookReferenceImage.objects.all().delete() + BookAuthor.objects.all().delete() + BookReference.objects.all().delete() + self.stdout.write(self.style.SUCCESS('Data cleared successfully!')) + + # Create authors first + authors_data = [ + {"name": "Imam Muhammad al-Bukhari"}, + {"name": "Imam Muslim ibn al-Hajjaj"}, + {"name": "Imam Abu Dawood as-Sijistani"}, + {"name": "Imam At-Tirmidhi"}, + {"name": "Imam Ibn Majah"}, + {"name": "Imam Ahmad ibn Hanbal"}, + {"name": "Imam Al-Hakim"}, + {"name": "Imam Ad-Daraqutni"}, + ] + + authors = {} + for author_data in authors_data: + author, created = BookAuthor.objects.get_or_create( + name=author_data['name'] + ) + authors[author_data['name']] = author + if created: + self.stdout.write(self.style.SUCCESS(f'Created author: {author.name}')) + + # Create book references + books_data = [ + { + "title": "Sahih al-Bukhari", + "description": "The most authentic collection of hadith, compiled by Imam Muhammad al-Bukhari. Contains 7,563 ahadith.", + "language": "Arabic", + "isbn": "978-1-86043-009-6", + "volume": "9 volumes", + "year_of_publication": "1870", + "number_page": 1200, + "publisher": "Dar al-Kutub al-Ilmiyah", + "rate": 5.00, + "authors": ["Imam Muhammad al-Bukhari"], + "image_order": 1, + "attributes": { + "Collection Type": "Hadith Compilation", + "Number of Hadith": "7,563", + "Classification": "6 Books", + "Authenticity Grade": "Sahih (Authentic)", + "Compilation Period": "16 years", + } + }, + { + "title": "Sahih Muslim", + "description": "Second most authentic hadith collection compiled by Imam Muslim ibn al-Hajjaj. Contains 9,200 traditions.", + "language": "Arabic", + "isbn": "978-1-86043-010-2", + "volume": "5 volumes", + "year_of_publication": "1875", + "number_page": 1500, + "publisher": "Dar Ihya at-Turath al-Arabi", + "rate": 4.95, + "authors": ["Imam Muslim ibn al-Hajjaj"], + "image_order": 2, + "attributes": { + "Collection Type": "Hadith Compilation", + "Number of Hadith": "9,200", + "Classification": "43 Books", + "Authenticity Grade": "Sahih (Authentic)", + "Unique Hadith": "Approximately 4,000", + } + }, + { + "title": "Sunan Abu Dawood", + "description": "A comprehensive collection of hadith containing jurisprudential material, compiled by Imam Abu Dawood as-Sijistani.", + "language": "Arabic", + "isbn": "978-1-86043-011-9", + "volume": "4 volumes", + "year_of_publication": "1880", + "number_page": 1400, + "publisher": "Islamic Digital Library", + "rate": 4.80, + "authors": ["Imam Abu Dawood as-Sijistani"], + "image_order": 3, + "attributes": { + "Collection Type": "Sunan (Practice)", + "Number of Hadith": "5,274", + "Focus": "Jurisprudential Traditions", + "Number of Books": "43", + "Authenticity Grade": "Hasan to Sahih", + } + }, + { + "title": "Jami' at-Tirmidhi", + "description": "A major collection of hadith compiled by Imam At-Tirmidhi with his commentary and grading of narrations.", + "language": "Arabic", + "isbn": "978-1-86043-012-6", + "volume": "5 volumes", + "year_of_publication": "1892", + "number_page": 1350, + "publisher": "Dar ar-Risalah al-Alamiyah", + "rate": 4.85, + "authors": ["Imam At-Tirmidhi"], + "image_order": 4, + "attributes": { + "Collection Type": "Jami (Comprehensive)", + "Number of Hadith": "3,956", + "Notable Feature": "Grades each hadith", + "Categories": "63 Chapters", + "Authenticity Grade": "Various Grades", + } + }, + { + "title": "Sunan Ibn Majah", + "description": "A collection of hadith compiled by Imam Ibn Majah, one of the Six Canonical Hadith Collections.", + "language": "Arabic", + "isbn": "978-1-86043-013-3", + "volume": "2 volumes", + "year_of_publication": "1888", + "number_page": 900, + "publisher": "Dar Ihya al-Kutub al-Arabiyah", + "rate": 4.75, + "authors": ["Imam Ibn Majah"], + "image_order": 5, + "attributes": { + "Collection Type": "Sunan (Practice)", + "Number of Hadith": "4,341", + "Number of Books": "32", + "Notable Content": "Includes rare narrations", + "Authenticity Grade": "Mixed - requires verification", + } + }, + ] + + books = {} + for book_data in books_data: + # Extract author names + author_names = book_data.pop('authors', []) + image_order = book_data.pop('image_order', 1) + attributes_dict = book_data.pop('attributes', {}) + + # Create or get the book + book, created = BookReference.objects.get_or_create( + title=book_data['title'], + defaults=book_data + ) + + if created: + self.stdout.write(self.style.SUCCESS(f'Created book: {book.title}')) + else: + # Update existing book + for key, value in book_data.items(): + setattr(book, key, value) + book.save() + self.stdout.write(self.style.WARNING(f'Updated book: {book.title}')) + + books[book.title] = book + + # Add authors to book + for author_name in author_names: + author = authors.get(author_name) + if author: + book.authors.add(author) + + # Add book image + image_path = self._get_image_path(image_order) + if image_path and os.path.exists(image_path): + # Check if image already exists for this book + if not book.images.exists(): + with open(image_path, 'rb') as img_file: + image_name = f'book{image_order}.png' + book_image = BookReferenceImage.objects.create( + book_reference=book, + order=1, + description=f"Cover image for {book.title}" + ) + book_image.image.save( + image_name, + ContentFile(img_file.read()), + save=True + ) + self.stdout.write( + self.style.SUCCESS(f'Added image to: {book.title}') + ) + else: + self.stdout.write( + self.style.WARNING( + f'Image not found at {image_path} for {book.title}' + ) + ) + + # Add attributes + for attr_title, attr_value in attributes_dict.items(): + attribute, created = BookAttribute.objects.get_or_create( + book_reference=book, + title=attr_title, + defaults={'value': attr_value} + ) + if created: + self.stdout.write( + self.style.SUCCESS( + f'Added attribute: {attr_title} to {book.title}' + ) + ) + + self.stdout.write( + self.style.SUCCESS( + f'\n✓ Successfully seeded {len(books)} books with all relations!' + ) + ) + self._print_summary() + + def _get_image_path(self, book_number): + """ + Find the image file for the given book number. + Checks multiple possible locations. + """ + possible_paths = [ + Path('seeds/images') / f'book{book_number}.png', + Path('seed_data/images') / f'book{book_number}.png', + Path('static/images') / f'book{book_number}.png', + Path('.') / 'seeds' / 'images' / f'book{book_number}.png', + ] + + for path in possible_paths: + if path.exists(): + return path + + return None + + def _print_summary(self): + """Print a summary of created data""" + self.stdout.write("\n" + "="*60) + self.stdout.write(self.style.SUCCESS("DATABASE SUMMARY")) + self.stdout.write("="*60) + + books_count = BookReference.objects.count() + authors_count = BookAuthor.objects.count() + images_count = BookReferenceImage.objects.count() + attributes_count = BookAttribute.objects.count() + + self.stdout.write(f"📚 Total Books: {books_count}") + self.stdout.write(f"✍️ Total Authors: {authors_count}") + self.stdout.write(f"🖼️ Total Images: {images_count}") + self.stdout.write(f"🏷️ Total Attributes: {attributes_count}") + self.stdout.write("="*60 + "\n") \ No newline at end of file diff --git a/seeds/images/image 1208.png b/seeds/images/image 1208.png new file mode 100644 index 0000000000000000000000000000000000000000..49d329d07bf605d77b5692991c72eb076fb44c02 GIT binary patch literal 16638 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 literal 0 HcmV?d00001 diff --git a/seeds/images/ref1.png b/seeds/images/ref1.png new file mode 100644 index 0000000000000000000000000000000000000000..7e3e4e76285e82b57ec805ebab4198d48f5c0419 GIT binary patch literal 60583 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 literal 0 HcmV?d00001 diff --git a/seeds/images/ref3.png b/seeds/images/ref3.png new file mode 100644 index 0000000000000000000000000000000000000000..0a7a4b592b30d9bbf71ab1cdf3b0535c29d121a8 GIT binary patch literal 8964 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 literal 0 HcmV?d00001