#!/usr/bin/env python3 """ Comprehensive data seeding script for Hadis app models. This script creates realistic sample records for all Hadis app models while maintaining proper relationships and business domain logic. """ import os import sys import django from pathlib import Path from django.core.files import File from django.core.files.base import ContentFile from django.db import transaction, models import random # Setup Django environment BASE_DIR = Path(__file__).resolve().parent.parent sys.path.append(str(BASE_DIR)) os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.base') django.setup() # Import models after Django setup from apps.hadis.models import ( HadisSect, HadisCategory, HadisStatus, HadisTag, Hadis, Transmitters, HadisTransmitter, HadisReference, ReferenceImage ) from apps.library.models import Book, Category as LibraryCategory, BookCollection class HadisDataSeeder: """Main seeder class for Hadis app data""" def __init__(self): self.script_dir = Path(__file__).parent self.seed_images_dir = self.script_dir / 'seed_images' self.xmind_file_path = self.script_dir / 'test.xmind' # Verify required files exist if not self.seed_images_dir.exists(): raise FileNotFoundError(f"Seed images directory not found: {self.seed_images_dir}") # XMind file is optional # if not self.xmind_file_path.exists(): # raise FileNotFoundError(f"XMind file not found: {self.xmind_file_path}") # Get available images self.image_files = list(self.seed_images_dir.glob('*.png')) if not self.image_files: raise FileNotFoundError("No PNG images found in seed_images directory") print(f"Found {len(self.image_files)} seed images") print(f"XMind file: {self.xmind_file_path}") def clear_existing_data(self): """Clear existing hadis data (optional - for clean seeding)""" print("Clearing existing hadis data...") # Clear in reverse dependency order ReferenceImage.objects.all().delete() HadisReference.objects.all().delete() HadisTransmitter.objects.all().delete() Hadis.objects.all().delete() HadisCategory.objects.all().delete() HadisSect.objects.all().delete() HadisStatus.objects.all().delete() HadisTag.objects.all().delete() Transmitters.objects.all().delete() print("Existing data cleared.") def seed_hadis_statuses(self): """Create HadisStatus records""" print("Creating Hadis Statuses...") statuses_data = [ {'title': 'Достоверный', 'color': 'green', 'order': 1}, {'title': 'Хороший', 'color': 'blue', 'order': 2}, {'title': 'Слабый', 'color': 'yellow', 'order': 3}, {'title': 'Выдуманный', 'color': 'red', 'order': 4}, {'title': 'Прерванный', 'color': 'orange', 'order': 5}, {'title': 'Разорванный', 'color': 'purple', 'order': 6}, {'title': 'Неизвестный', 'color': 'gray', 'order': 7}, ] statuses = [] for data in statuses_data: status, created = HadisStatus.objects.get_or_create( title=data['title'], defaults=data ) statuses.append(status) if created: print(f" Created status: {status.title}") return statuses def seed_hadis_tags(self): """Create HadisTag records""" print("Creating Hadis Tags...") tags_data = [ 'Поклонение', 'Молитва', 'Пост', 'Хадж', 'Закят', 'Хумс', 'Нравственность', 'Терпение', 'Благодарность', 'Упование', 'Богобоязненность', 'Справедливость', 'Фикх', 'Предписания', 'Дозволенное', 'Запретное', 'Желательное', 'Нежелательное', 'Толкование', 'Коран', 'Аяты', 'Сура', 'Чтение', 'Имамат', 'Власть', 'Непорочные', 'Семья Пророка', 'Мольба', 'Поминание', 'Прощение', 'Восхваление', 'Единобожие' ] tags = [] for tag_title in tags_data: tag, created = HadisTag.objects.get_or_create( title=tag_title, defaults={'status': True} ) tags.append(tag) if created: print(f" Created tag: {tag.title}") return tags def seed_hadis_sects(self): """Create HadisSect records""" print("Creating Hadis Sects...") sects_data = [ {'sect_type': 'shia', 'title': 'Шииты-двунадесятники', 'is_active': True, 'order': 1}, {'sect_type': 'sunni', 'title': 'Сунниты', 'is_active': True, 'order': 2}, ] sects = [] for data in sects_data: sect, created = HadisSect.objects.get_or_create( sect_type=data['sect_type'], defaults=data ) sects.append(sect) if created: print(f" Created sect: {sect.title}") return sects def assign_xmind_file(self, category): """Assign XMind file to category""" try: with open(self.xmind_file_path, 'rb') as f: file_content = f.read() # Create unique filename for each category filename = f"category_{category.id}_{category.title[:20]}.xmind" category.xmind_file.save( filename, ContentFile(file_content), save=True ) return True except Exception as e: print(f" Warning: Could not assign XMind file to {category.title}: {e}") return False def seed_hadis_categories(self, sects): """Create HadisCategory records with hierarchical structure - optimized batch creation""" print("Creating Hadis Categories...") categories = [] categories_to_create = [] categories_to_update = [] for sect in sects: print(f" Creating categories for {sect.title}...") # Quran categories quran_categories_data = [ {'title': 'Толкование Корана', 'order': 1}, {'title': 'Аяты предписаний', 'order': 2}, {'title': 'Рассказы Корана', 'order': 3}, {'title': 'Достоинства сур', 'order': 4}, {'title': 'Чудеса Корана', 'order': 5}, {'title': 'Коранические науки', 'order': 6}, ] # First, get existing categories to avoid duplicates existing_quran_categories = { cat.title: cat for cat in HadisCategory.objects.filter( sect=sect, source_type='quran', parent=None ) } # Process main Quran categories for cat_data in quran_categories_data: if cat_data['title'] in existing_quran_categories: category = existing_quran_categories[cat_data['title']] if category.order != cat_data['order']: category.order = cat_data['order'] categories_to_update.append(category) print(f" Will update Quran category: {category.title}") else: print(f" Quran category exists: {category.title}") else: category = HadisCategory( sect=sect, source_type='quran', title=cat_data['title'], order=cat_data['order'] ) categories_to_create.append(category) print(f" Will create Quran category: {cat_data['title']}") categories.append(category) # Batch create new categories if categories_to_create: HadisCategory.objects.bulk_create(categories_to_create, ignore_conflicts=True) print(f" Batch created {len(categories_to_create)} Quran categories") categories_to_create = [] # Batch update existing categories if categories_to_update: HadisCategory.objects.bulk_update(categories_to_update, ['order']) print(f" Batch updated {len(categories_to_update)} Quran categories") categories_to_update = [] # Now handle child categories parent_categories = HadisCategory.objects.filter( sect=sect, source_type='quran', parent=None ) for parent_category in parent_categories: child_categories_data = [] if parent_category.title == 'Толкование Корана': child_categories_data = [ {'title': 'Толкование суры Аль-Фатиха', 'order': 1}, {'title': 'Толкование суры Аль-Бакара', 'order': 2}, {'title': 'Толкование суры Аль Имран', 'order': 3}, {'title': 'Толкование суры Ан-Ниса', 'order': 4}, {'title': 'Толкование суры Аль-Маида', 'order': 5}, ] elif parent_category.title == 'Аяты предписаний': child_categories_data = [ {'title': 'Аяты о молитве', 'order': 1}, {'title': 'Аяты о посте', 'order': 2}, {'title': 'Аяты о закяте', 'order': 3}, {'title': 'Аяты о хадже', 'order': 4}, ] elif parent_category.title == 'Рассказы Корана': child_categories_data = [ {'title': 'История пророков', 'order': 1}, {'title': 'Рассказы о праведниках', 'order': 2}, {'title': 'Уроки из истории', 'order': 3}, ] elif parent_category.title == 'Достоинства сур': child_categories_data = [ {'title': 'Достоинства суры Аль-Фатиха', 'order': 1}, {'title': 'Достоинства суры Аль-Бакара', 'order': 2}, {'title': 'Достоинства суры Йа-Син', 'order': 3}, {'title': 'Достоинства суры Аль-Мульк', 'order': 4}, ] if child_categories_data: # Get existing child categories existing_children = { cat.title: cat for cat in HadisCategory.objects.filter( parent=parent_category, sect=sect, source_type='quran' ) } # Process child categories for child_data in child_categories_data: if child_data['title'] in existing_children: child_category = existing_children[child_data['title']] if child_category.order != child_data['order']: child_category.order = child_data['order'] categories_to_update.append(child_category) print(f" Will update child category: {child_category.title}") else: print(f" Child category exists: {child_category.title}") else: child_category = HadisCategory( parent=parent_category, sect=sect, source_type='quran', title=child_data['title'], order=child_data['order'] ) categories_to_create.append(child_category) print(f" Will create child category: {child_data['title']}") categories.append(child_category) # Batch operations for child categories if categories_to_create: HadisCategory.objects.bulk_create(categories_to_create, ignore_conflicts=True) print(f" Batch created {len(categories_to_create)} child categories") categories_to_create = [] if categories_to_update: HadisCategory.objects.bulk_update(categories_to_update, ['order']) print(f" Batch updated {len(categories_to_update)} child categories") categories_to_update = [] # Assign XMind file to some categories (after creation) if random.choice([True, False]) and not parent_category.xmind_file: self.assign_xmind_file(parent_category) # Hadith categories - optimized batch processing hadith_categories_data = [ {'title': 'Книга очищения', 'order': 1}, {'title': 'Книга молитвы', 'order': 2}, {'title': 'Книга поста', 'order': 3}, {'title': 'Книга хаджа', 'order': 4}, {'title': 'Книга закята', 'order': 5}, {'title': 'Книга брака', 'order': 6}, {'title': 'Книга нравственности', 'order': 7}, {'title': 'Книга торговли', 'order': 8}, {'title': 'Книга джихада', 'order': 9}, {'title': 'Книга судопроизводства', 'order': 10}, ] # Get existing hadith categories existing_hadith_categories = { cat.title: cat for cat in HadisCategory.objects.filter( sect=sect, source_type='hadith', parent=None ) } categories_to_create = [] categories_to_update = [] # Process main Hadith categories for cat_data in hadith_categories_data: if cat_data['title'] in existing_hadith_categories: category = existing_hadith_categories[cat_data['title']] if category.order != cat_data['order']: category.order = cat_data['order'] categories_to_update.append(category) print(f" Will update Hadith category: {category.title}") else: print(f" Hadith category exists: {category.title}") else: category = HadisCategory( sect=sect, source_type='hadith', title=cat_data['title'], order=cat_data['order'] ) categories_to_create.append(category) print(f" Will create Hadith category: {cat_data['title']}") categories.append(category) # Batch create new hadith categories if categories_to_create: HadisCategory.objects.bulk_create(categories_to_create, ignore_conflicts=True) print(f" Batch created {len(categories_to_create)} Hadith categories") # Batch update existing hadith categories if categories_to_update: HadisCategory.objects.bulk_update(categories_to_update, ['order']) print(f" Batch updated {len(categories_to_update)} Hadith categories") # Now handle hadith child categories parent_categories = HadisCategory.objects.filter( sect=sect, source_type='hadith', parent=None ) for parent_category in parent_categories: child_categories_data = [] if parent_category.title == 'Книга очищения': child_categories_data = [ {'title': 'Омовение', 'order': 1}, {'title': 'Полное омовение', 'order': 2}, {'title': 'Сухое омовение', 'order': 3}, {'title': 'Нечистоты', 'order': 4}, ] elif parent_category.title == 'Книга молитвы': child_categories_data = [ {'title': 'Времена молитвы', 'order': 1}, {'title': 'Кибла', 'order': 2}, {'title': 'Азан и икама', 'order': 3}, {'title': 'Коллективная молитва', 'order': 4}, {'title': 'Пятничная молитва', 'order': 5}, ] elif parent_category.title == 'Книга поста': child_categories_data = [ {'title': 'Пост в Рамадан', 'order': 1}, {'title': 'Добровольный пост', 'order': 2}, {'title': 'Нарушители поста', 'order': 3}, {'title': 'Ночь предопределения', 'order': 4}, ] elif parent_category.title == 'Книга хаджа': child_categories_data = [ {'title': 'Обряды хаджа', 'order': 1}, {'title': 'Умра', 'order': 2}, {'title': 'Запреты ихрама', 'order': 3}, ] elif parent_category.title == 'Книга нравственности': child_categories_data = [ {'title': 'Терпение и благодарность', 'order': 1}, {'title': 'Справедливость и честность', 'order': 2}, {'title': 'Знание и мудрость', 'order': 3}, {'title': 'Дружба и братство', 'order': 4}, ] if child_categories_data: # Get existing child categories existing_children = { cat.title: cat for cat in HadisCategory.objects.filter( parent=parent_category, sect=sect, source_type='hadith' ) } categories_to_create = [] categories_to_update = [] # Process child categories for child_data in child_categories_data: if child_data['title'] in existing_children: child_category = existing_children[child_data['title']] if child_category.order != child_data['order']: child_category.order = child_data['order'] categories_to_update.append(child_category) print(f" Will update child category: {child_category.title}") else: print(f" Child category exists: {child_category.title}") else: child_category = HadisCategory( parent=parent_category, sect=sect, source_type='hadith', title=child_data['title'], order=child_data['order'] ) categories_to_create.append(child_category) print(f" Will create child category: {child_data['title']}") categories.append(child_category) # Batch operations for child categories if categories_to_create: HadisCategory.objects.bulk_create(categories_to_create, ignore_conflicts=True) print(f" Batch created {len(categories_to_create)} child categories") if categories_to_update: HadisCategory.objects.bulk_update(categories_to_update, ['order']) print(f" Batch updated {len(categories_to_update)} child categories") # Assign XMind file to some categories (after creation) if random.choice([True, False]) and not parent_category.xmind_file: self.assign_xmind_file(parent_category) return categories def seed_library_data(self): """Create library data (books, categories, collections) for references""" print("Creating Library data...") # Create library categories lib_categories_data = [ 'Книги хадисов', 'Книги фикха', 'Книги толкования', 'Книги нравственности', 'Исторические книги' ] lib_categories = [] for cat_title in lib_categories_data: category, created = LibraryCategory.objects.get_or_create( title=cat_title, defaults={'status': True} ) lib_categories.append(category) if created: print(f" Created library category: {category.title}") # Create book collections collections_data = [ {'title': 'Шиитские книги хадисов', 'display_position': 'pinned'}, {'title': 'Суннитские книги хадисов', 'display_position': 'middle'}, {'title': 'Сборник книг по фикху', 'display_position': 'middle'}, ] collections = [] for coll_data in collections_data: collection, created = BookCollection.objects.get_or_create( title=coll_data['title'], defaults={ 'summary': f'Коллекция {coll_data["title"]}', 'display_position': coll_data['display_position'], 'status': True, 'order': len(collections) + 1 } ) collections.append(collection) if created: print(f" Created collection: {collection.title}") # Create books with cover images books_data = [ { 'title': 'Аль-Кафи', 'summary_title': 'Книга Аль-Кафи шейха Кулейни', 'summary': 'Одна из важнейших книг хадисов шиитов', 'description': 'Книга Аль-Кафи, написанная Мухаммадом ибн Якубом Кулейни, является одной из четырех достоверных книг хадисов шиитов.', 'publisher': 'Дар аль-Кутуб аль-Исламийя', 'year_of_publication': '1407', 'isbn': '978-964-372-001-1', 'pages_count': '2847', 'file_type': 'pdf' }, { 'title': 'Сахих аль-Бухари', 'summary_title': 'Сахих аль-Бухари имама Бухари', 'summary': 'Самая достоверная книга хадисов суннитов', 'description': 'Сахих аль-Бухари, написанный Мухаммадом ибн Исмаилом Бухари, является самой достоверной книгой хадисов у суннитов.', 'publisher': 'Дар Тук ан-Наджа', 'year_of_publication': '1422', 'isbn': '978-964-372-002-2', 'pages_count': '1896', 'file_type': 'pdf' }, { 'title': 'Ман ля яхдуруху аль-факих', 'summary_title': 'Ман ля яхдуруху аль-факих шейха Садука', 'summary': 'Важная книга по фикху и хадисам шиитов', 'description': 'Книга Ман ля яхдуруху аль-факих, написанная шейхом Садуком, является одной из четырех книг шиитов.', 'publisher': 'Муассаса ан-Нашр аль-Ислами', 'year_of_publication': '1413', 'isbn': '978-964-372-003-3', 'pages_count': '1524', 'file_type': 'pdf' }, { 'title': 'Сунан Абу Дауд', 'summary_title': 'Сунан Абу Дауд имама Абу Дауда', 'summary': 'Одна из шести книг суннитов', 'description': 'Сунан Абу Дауд, написанная Сулейманом ибн Ашасом Сиджистани, является одной из шести книг суннитов.', 'publisher': 'Аль-Мактаба аль-Асрийя', 'year_of_publication': '1430', 'isbn': '978-964-372-004-4', 'pages_count': '1342', 'file_type': 'pdf' }, ] books = [] for i, book_data in enumerate(books_data): # Get random image for book cover image_file = random.choice(self.image_files) book, created = Book.objects.get_or_create( title=book_data['title'], defaults=book_data ) if created: # Assign cover image try: with open(image_file, 'rb') as f: book.thumbnail.save( f"book_cover_{book.id}.png", File(f), save=True ) print(f" Created book: {book.title} with cover image") except Exception as e: print(f" Created book: {book.title} (no cover image: {e})") # Assign to categories and collections if lib_categories: book.categories.add(random.choice(lib_categories)) if collections: book.collections.add(random.choice(collections)) books.append(book) return books, lib_categories, collections def seed_transmitters(self): """Create Transmitters records""" print("Creating Transmitters...") transmitters_data = [ { 'full_name': 'Мухаммад ибн Якуб Кулейни', 'birth_year_hijri': 250, 'death_year_hijri': 329, 'description': 'Шейх Кулейни, автор книги Аль-Кафи и один из великих мухаддисов шиитов' }, { 'full_name': 'Мухаммад ибн Али ибн Бабавейх (Шейх Садук)', 'birth_year_hijri': 306, 'death_year_hijri': 381, 'description': 'Шейх Садук, автор книги Ман ля яхдуруху аль-факих' }, { 'full_name': 'Мухаммад ибн аль-Хасан ат-Туси', 'birth_year_hijri': 385, 'death_year_hijri': 460, 'description': 'Шейх Туси, автор книг Тахзиб аль-Ахкам и аль-Истибсар' }, { 'full_name': 'Мухаммад ибн Исмаил аль-Бухари', 'birth_year_hijri': 194, 'death_year_hijri': 256, 'description': 'Имам Бухари, автор Сахих аль-Бухари' }, { 'full_name': 'Муслим ибн аль-Хаджжадж ан-Нишапури', 'birth_year_hijri': 206, 'death_year_hijri': 261, 'description': 'Имам Муслим, автор Сахих Муслим' }, { 'full_name': 'Абу Дауд ас-Сиджистани', 'birth_year_hijri': 202, 'death_year_hijri': 275, 'description': 'Имам Абу Дауд, автор Сунан Абу Дауд' }, { 'full_name': 'Джафар ибн Мухаммад ас-Садик', 'birth_year_hijri': 83, 'death_year_hijri': 148, 'description': 'Имам Джафар Садик (мир ему), шестой имам шиитов' }, { 'full_name': 'Мухаммад ибн Али аль-Бакир', 'birth_year_hijri': 57, 'death_year_hijri': 114, 'description': 'Имам Мухаммад Бакир (мир ему), пятый имам шиитов' }, { 'full_name': 'Али ибн аль-Хусейн ас-Саджжад', 'birth_year_hijri': 38, 'death_year_hijri': 95, 'description': 'Имам Али ибн аль-Хусейн (мир ему), четвертый имам шиитов' }, { 'full_name': 'Мухаммад ибн Муслим', 'birth_year_hijri': 70, 'death_year_hijri': 150, 'description': 'Мухаммад ибн Муслим, из сподвижников имама Бакира и имама Садика (мир им)' }, ] transmitters = [] for trans_data in transmitters_data: transmitter, created = Transmitters.objects.get_or_create( full_name=trans_data['full_name'], defaults=trans_data ) transmitters.append(transmitter) if created: print(f" Created transmitter: {transmitter.full_name}") return transmitters def seed_hadis_records(self, categories, statuses, tags, transmitters, books): """Create Hadis records with proper relationships - optimized batch creation""" print("Creating Hadis records...") # Get only leaf categories (categories without children) - optimized query leaf_categories = HadisCategory.objects.filter( id__in=[cat.id for cat in categories] ).annotate( children_count=models.Count('children') ).filter(children_count=0) print(f"Found {len(leaf_categories)} leaf categories for hadis creation") # Comprehensive hadis samples with longer texts hadis_samples = { 'prayer': [ { 'title': 'Достоинство молитвы и ее место в религии', 'text': '''قال رسول الله صلى الله عليه وآله: الصلاة عمود الدين، إن قبلت قبل ما سواها، وإن ردت رد ما سواها. وهي أول ما يحاسب عليه العبد يوم القيامة، فإن صلحت صلح سائر عمله، وإن فسدت فسد سائر عمله. والصلاة معراج المؤمن، وهي قربان كل تقي، وهي حب الله تعالى. من أحبها وأقامها في أوقاتها وحافظ على حدودها رفعه الله إلى درجة الأبرار. ومن استخف بها وضيعها وتركها فقد استخف بدين الله، ولا نصيب له في الإسلام. إن الله تعالى فرض خمس صلوات في اليوم والليلة، وجعل لكل صلاة وقتاً معلوماً، فمن صلاها في وقتها وأتم ركوعها وسجودها وخشوعها، كانت له نوراً وبرهاناً ونجاة يوم القيامة.''', 'translation': [ {'language_code': 'ru', 'title': '''Сказал Посланник Аллаха (да благословит Аллах его и его семейство): Молитва - столп религии, если она принята, то принято и остальное, а если отвергнута, то отвергнуто и остальное. Это первое, за что будет спрошен раб в День Воскресения, и если она будет правильной, то правильными будут и остальные его дела, а если испорчена, то испорчены и остальные его дела. Молитва - это вознесение верующего, она - приношение каждого богобоязненного, она - любовь Всевышнего Аллаха. Кто полюбил ее и совершал ее в установленные времена и соблюдал ее границы, того Аллах возвысит до степени праведников. А кто пренебрег ею, потерял ее и оставил, тот пренебрег религией Аллаха, и нет ему доли в Исламе. Поистине, Всевышний Аллах предписал пять молитв в сутки и установил для каждой молитвы определенное время. Кто совершал их в свое время и завершал их поклоны, земные поклоны и смирение, для того они станут светом, доказательством и спасением в День Воскресения.'''}, {'language_code': 'fa', 'title': '''رسول خدا فرمود: نماز ستون دین است، اگر پذیرفته شود غیر آن نیز پذیرفته می‌شود و اگر رد شود غیر آن نیز رد می‌شود. و این اولین چیزی است که بنده در روز قیامت از آن بازخواست می‌شود، پس اگر درست باشد تمام اعمالش درست است و اگر فاسد باشد تمام اعمالش فاسد است. نماز معراج مؤمن است و قربانی هر پرهیزکار و محبت خداوند متعال است. هر کس آن را دوست بدارد و در اوقاتش برپا دارد و حدودش را نگه دارد، خداوند او را به درجه نیکان بالا می‌برد. و هر کس آن را سبک بشمارد و ضایع کند و ترک کند، دین خدا را سبک شمرده و بهره‌ای در اسلام ندارد. خداوند متعال پنج نماز در شبانه‌روز واجب کرده و برای هر نماز وقت معینی قرار داده، پس هر کس آن‌ها را در وقتشان بخواند و رکوع و سجود و خشوعشان را کامل کند، برایش نور و برهان و نجات در روز قیامت خواهد بود.'''}, {'language_code': 'en', 'title': '''The Messenger of Allah said: Prayer is the pillar of religion, if it is accepted, other deeds are accepted, and if it is rejected, other deeds are rejected. It is the first thing for which a servant will be held accountable on the Day of Judgment, and if it is sound, all his other deeds will be sound, and if it is corrupted, all his other deeds will be corrupted. Prayer is the ascension of the believer, it is the offering of every God-fearing person, and it is the love of Allah the Almighty. Whoever loves it and establishes it at its times and maintains its boundaries, Allah will raise him to the rank of the righteous. And whoever takes it lightly, wastes it and abandons it, has taken Allah's religion lightly, and has no share in Islam. Indeed, Allah the Almighty has prescribed five prayers in a day and night, and has appointed a specific time for each prayer. Whoever prays them at their time and completes their bowing, prostration and humility, they will be light, proof and salvation for him on the Day of Judgment.'''} ], 'explanation': '''Этот обширный хадис представляет собой фундаментальное учение о молитве в Исламе. Он раскрывает несколько ключевых аспектов: Во-первых, молитва описывается как "столп религии" (عمود الدين), что указывает на ее центральную роль в исламской вере. Это метафора подчеркивает, что как здание не может стоять без столпов, так и религиозная жизнь мусульманина не может быть полноценной без молитвы. Во-вторых, хадис устанавливает принцип, согласно которому принятие или отвержение молитвы Аллахом определяет судьбу всех остальных деяний верующего. Это подчеркивает качественный аспект молитвы - важна не только ее форма, но и искренность, концентрация и правильное выполнение. В-третьих, молитва представлена как "معراج المؤمن" (вознесение верующего), что отсылает к ночному путешествию Пророка (мир ему) и подчеркивает духовное измерение молитвы как средства приближения к Всевышнему. Хадис также подчеркивает важность своевременного совершения молитв и соблюдения их внешних и внутренних условий, обещая великую награду тем, кто относится к молитве с должным вниманием и уважением.''' }, { 'title': 'Времена молитвы', 'text': 'عن أبي عبد الله عليه السلام قال: إن لكل صلاة وقتين، وأول الوقت أفضل من آخره.', 'translation': [ {'language_code': 'ru', 'title': 'От Абу Абдуллаха (мир ему) сказал: Поистине, у каждой молитвы два времени, и первое время лучше последнего.'}, {'language_code': 'fa', 'title': 'از امام صادق علیه السلام: هر نمازی دو وقت دارد و اول وقت بهتر از آخر آن است.'}, {'language_code': 'en', 'title': 'From Imam Sadiq: Every prayer has two times, and the first time is better than the last.'} ], 'explanation': 'Этот хадис касается времен молитвы и достоинства совершения молитвы в первое время.' }, { 'title': 'Коллективная молитва и ее великая награда', 'text': '''قال رسول الله صلى الله عليه وآله: صلاة الجماعة تفضل صلاة الفذ بسبع وعشرين درجة. وما من رجل يؤم قوماً إلا غفر له ما تقدم من ذنبه وما تأخر، وما من رجل يصلي خلف إمام إلا كتب له مثل أجر الإمام من غير أن ينقص من أجر الإمام شيء. وإن الملائكة لتصلي على الصف الأول، وإن الشيطان ليفر من صوت الأذان، وإن الله تعالى يباهي بالمصلين ملائكته. ومن صلى في جماعة أربعين يوماً لا تفوته التكبيرة الأولى كتب له براءتان: براءة من النار وبراءة من النفاق. فاحرصوا على صلاة الجماعة، فإنها من شعائر الإسلام العظيمة، وهي سبب للألفة والمحبة بين المؤمنين، وفيها تظهر وحدة الأمة وقوتها.''', 'translation': [ {'language_code': 'ru', 'title': '''Сказал Посланник Аллаха (да благословит Аллах его и его семейство): Коллективная молитва превосходит индивидуальную молитву на двадцать семь степеней. И нет человека, который бы руководил молитвой людей, кроме как ему прощаются его прошлые и будущие грехи, и нет человека, который молился бы за имамом, кроме как ему записывается такая же награда, как имаму, не уменьшая награды имама ни на что. Поистине, ангелы молятся за первый ряд, и шайтан убегает от звука азана, и Всевышний Аллах гордится молящимися перед Своими ангелами. И кто молился в коллективе сорок дней, не пропуская первый такбир, тому записываются два освобождения: освобождение от огня и освобождение от лицемерия. Так стремитесь к коллективной молитве, ибо она из великих обрядов Ислама, и она причина единства и любви между верующими, и в ней проявляется единство уммы и ее сила.'''}, {'language_code': 'fa', 'title': '''رسول خدا فرمود: نماز جماعت بر نماز فردی بیست و هفت درجه برتری دارد. و هیچ مردی نیست که امامت قومی کند مگر اینکه گناهان گذشته و آینده‌اش آمرزیده می‌شود، و هیچ مردی نیست که پشت سر امام نماز بخواند مگر اینکه مثل پاداش امام برایش نوشته می‌شود بدون اینکه از پاداش امام چیزی کم شود. همانا فرشتگان بر صف اول درود می‌فرستند و شیطان از صدای اذان فرار می‌کند و خداوند متعال به نمازگزاران در برابر فرشتگانش فخر می‌کند. و هر کس چهل روز در جماعت نماز بخواند که تکبیر اول را از دست ندهد، دو برائت برایش نوشته می‌شود: برائت از آتش و برائت از نفاق. پس بر نماز جماعت حریص باشید که از شعائر بزرگ اسلام است و سبب الفت و محبت میان مؤمنان است و در آن وحدت امت و قدرتش ظاهر می‌شود.'''}, {'language_code': 'en', 'title': '''The Messenger of Allah said: Congregational prayer is superior to individual prayer by twenty-seven degrees. There is no man who leads people in prayer except that his past and future sins are forgiven, and there is no man who prays behind an imam except that the same reward as the imam is written for him without diminishing anything from the imam's reward. Indeed, the angels pray for the first row, and Satan flees from the sound of the call to prayer, and Allah the Almighty boasts of those who pray to His angels. And whoever prays in congregation for forty days without missing the first takbir, two clearances are written for him: clearance from the Fire and clearance from hypocrisy. So be keen on congregational prayer, for it is one of the great rituals of Islam, and it is a cause of harmony and love among believers, and in it the unity and strength of the ummah is manifested.'''} ], 'explanation': '''Этот развернутый хадис раскрывает множественные аспекты коллективной молитвы в Исламе и ее огромное духовное значение. Прежде всего, хадис устанавливает количественное превосходство коллективной молитвы над индивидуальной - в двадцать семь раз. Это число не случайно и подчеркивает особую ценность единения верующих в поклонении. Особое внимание уделяется роли имама и участников коллективной молитвы. Имам получает прощение грехов, что подчеркивает ответственность руководства общиной в молитве. Участники же получают равную награду с имамом, что демонстрирует справедливость божественного воздаяния. Хадис также упоминает о духовных реалиях, невидимых человеческому глазу: молитвы ангелов за первый ряд, бегство шайтана от азана, и гордость Всевышнего Своими поклоняющимися рабами. Особая награда обещана тем, кто постоянно участвует в коллективной молитве в течение сорока дней - это освобождение от огня и от лицемерия, что указывает на очищающую силу регулярного коллективного поклонения. Наконец, хадис подчеркивает социальный аспект коллективной молитвы как средства укрепления единства мусульманской общины.''' }, { 'title': 'Времена молитв и их сохранение', 'text': '''عن أبي عبد الله عليه السلام قال: إن لكل صلاة وقتين، وأول الوقت أفضل من آخره إلا في العشاء الآخرة، فإن أفضل وقتها إذا ذهب ثلث الليل. وقال: من صلى في أول الوقت فقد أدرك فضل الوقت، ومن صلى في آخر الوقت فقد أدرك الوقت. وحافظوا على الصلوات والصلاة الوسطى وقوموا لله قانتين. والصلاة الوسطى هي صلاة الظهر، وهي أول صلاة صلاها رسول الله صلى الله عليه وآله، وهي وسط النهار. إن الله تعالى جعل لكل صلاة علامات يعرف بها وقتها: فالفجر عند طلوع الفجر الصادق، والظهر عند زوال الشمس، والعصر عند صيرورة ظل كل شيء مثله، والمغرب عند غروب الشمس، والعشاء عند ذهاب الشفق الأحمر.''', 'translation': [ {'language_code': 'ru', 'title': '''От Абу Абдуллаха (мир ему): Поистине, у каждой молитвы два времени, и первое время лучше последнего, кроме ночной молитвы (иша), ибо лучшее время для нее - когда пройдет треть ночи. И сказал: кто помолился в первое время, тот достиг достоинства времени, а кто помолился в последнее время, тот достиг времени. Соблюдайте молитвы и среднюю молитву, и стойте перед Аллахом смиренно. Средняя молитва - это полуденная молитва, и это первая молитва, которую совершил Посланник Аллаха (да благословит Аллах его и его семейство), и она в середине дня. Поистине, Всевышний Аллах установил для каждой молитвы признаки, по которым узнается ее время: утренняя - при появлении истинного рассвета, полуденная - при прохождении солнца через зенит, послеполуденная - когда тень каждой вещи становится равной ей, вечерняя - при заходе солнца, ночная - при исчезновении красной зари.'''}, {'language_code': 'fa', 'title': '''از امام صادق علیه السلام: همانا هر نمازی دو وقت دارد و اول وقت بهتر از آخر آن است مگر نماز عشاء که بهترین وقتش زمانی است که یک سوم شب بگذرد. و فرمود: هر کس در اول وقت نماز بخواند فضیلت وقت را درک کرده و هر کس در آخر وقت بخواند وقت را درک کرده است. بر نمازها و نماز وسطی محافظت کنید و برای خدا فروتنانه بایستید. نماز وسطی همان نماز ظهر است و این اولین نمازی است که رسول خدا صلی الله علیه و آله خواند و در وسط روز است. خداوند متعال برای هر نماز علامت‌هایی قرار داده که وقتش با آن شناخته می‌شود: نماز صبح هنگام طلوع فجر صادق، نماز ظهر هنگام زوال آفتاب، نماز عصر هنگامی که سایه هر چیز مثل خودش شود، نماز مغرب هنگام غروب آفتاب، نماز عشاء هنگام رفتن شفق سرخ.'''}, {'language_code': 'en', 'title': '''From Abu Abdullah (peace be upon him): Indeed, every prayer has two times, and the first time is better than the last, except for the night prayer (Isha), for its best time is when a third of the night has passed. And he said: whoever prays at the first time has achieved the virtue of time, and whoever prays at the last time has achieved the time. Maintain the prayers and the middle prayer, and stand before Allah humbly. The middle prayer is the noon prayer, and it is the first prayer that the Messenger of Allah (may Allah bless him and his family) prayed, and it is in the middle of the day. Indeed, Allah the Almighty has established signs for each prayer by which its time is known: the dawn prayer at the appearance of true dawn, the noon prayer when the sun passes through the zenith, the afternoon prayer when the shadow of everything becomes equal to it, the evening prayer at sunset, the night prayer when the red twilight disappears.'''} ], 'explanation': '''Этот хадис представляет собой подробное руководство по временам молитв и их правильному соблюдению, что является одним из важнейших аспектов исламского поклонения. Хадис начинается с установления общего принципа о том, что каждая молитва имеет два времени - предпочтительное (первое) и допустимое (до конца времени). Это дает верующим гибкость в совершении молитв, учитывая различные жизненные обстоятельства, но при этом поощряет стремление к совершенству. Особое исключение делается для ночной молитвы (иша), для которой предпочтительное время наступает после прохождения трети ночи. Это связано с тем, что в это время достигается большее духовное сосредоточение и меньше мирских отвлечений. Хадис цитирует коранический аят о "средней молитве" и идентифицирует ее как полуденную молитву (зухр), подчеркивая ее особое значение как первой молитвы, установленной Пророком. Наконец, хадис предоставляет практическое руководство по определению времен молитв через естественные признаки, что было особенно важно в эпоху до появления точных часов. Эти признаки основаны на движении солнца и изменении освещения, что делает их универсально применимыми в любой географической точке.''' } ], 'fasting': [ { 'title': 'Достоинство поста и его духовные плоды', 'text': '''قال النبي صلى الله عليه وآله: الصوم جنة من النار، وهو زكاة البدن، وصوم شهر الصبر وثلاثة أيام من كل شهر يذهبن وحر الصدر ووساوس الشيطان. ومن صام يوماً في سبيل الله باعد الله وجهه عن النار سبعين خريفاً. إن الصائم في عبادة وإن كان نائماً على فراشه، وإن دعاءه مستجاب حتى يفطر، وإن الملائكة تستغفر له حتى يفطر. وللصائم فرحتان: فرحة عند فطره، وفرحة عند لقاء ربه. يا معشر الشباب، من استطاع منكم الباءة فليتزوج، ومن لم يستطع فعليه بالصوم فإنه له وجاء. والصوم يكسر الشهوة ويطهر النفس ويقرب إلى الله تعالى.''', 'translation': [ {'language_code': 'ru', 'title': '''Сказал Пророк (да благословит Аллах его и его семейство): Пост - щит от огня, и он закят тела, и пост месяца терпения и трех дней каждого месяца устраняют жар груди и наущения шайтана. И кто постился день на пути Аллаха, Аллах отдалит его лицо от огня на семьдесят осеней. Поистине, постящийся находится в поклонении, даже если он спит на своей постели, и его мольба принимается до тех пор, пока он не разговеется, и ангелы просят прощения для него до тех пор, пока он не разговеется. И у постящегося две радости: радость при разговении и радость при встрече со своим Господом. О молодежь! Кто из вас способен жениться, пусть женится, а кто не способен, пусть постится, ибо это для него защита. Пост ломает страсть, очищает душу и приближает к Всевышнему Аллаху.'''}, {'language_code': 'fa', 'title': '''پیامبر فرمود: روزه سپری است از آتش جهنم و زکات بدن است و روزه ماه صبر و سه روز از هر ماه، حرارت سینه و وسوسه‌های شیطان را می‌برد. و هر کس روزی در راه خدا روزه بگیرد، خداوند صورتش را از آتش به اندازه هفتاد پاییز دور می‌کند. روزه‌دار در عبادت است اگرچه بر بسترش خوابیده باشد و دعایش تا افطار مستجاب است و فرشتگان تا افطار برایش استغفار می‌کنند. و روزه‌دار را دو شادی است: شادی هنگام افطار و شادی هنگام ملاقات پروردگارش. ای جوانان! هر کس از شما توانایی ازدواج دارد باید ازدواج کند و هر کس نتواند باید روزه بگیرد که برایش محافظ است. روزه شهوت را می‌شکند و نفس را پاک می‌کند و به خداوند متعال نزدیک می‌کند.'''}, {'language_code': 'en', 'title': '''The Prophet said: Fasting is a shield from the Fire, and it is the zakat of the body, and fasting the month of patience and three days of each month removes the heat of the chest and the whispers of Satan. And whoever fasts a day in the way of Allah, Allah will distance his face from the Fire by seventy autumns. Indeed, the fasting person is in worship even if he is sleeping on his bed, and his supplication is answered until he breaks his fast, and the angels seek forgiveness for him until he breaks his fast. And the fasting person has two joys: joy when he breaks his fast, and joy when he meets his Lord. O young people! Whoever among you is able to marry, let him marry, and whoever is not able, let him fast, for it is a protection for him. Fasting breaks desire, purifies the soul, and brings one closer to Allah the Almighty.'''} ], 'explanation': '''Этот многогранный хадис раскрывает глубокие духовные и практические аспекты поста в Исламе, представляя его как комплексную систему духовного и физического очищения. Хадис начинается с определения поста как "щита от огня" (جنة من النار), что указывает на его защитную функцию от грехов и их последствий. Понятие "закят тела" (زكاة البدن) представляет пост как форму очищения физического тела, аналогичную тому, как закят очищает имущество. Особое внимание уделяется посту "месяца терпения" (شهر الصبر) - Рамадана, и дополнительным постам трех дней каждого месяца. Эти посты описываются как средство устранения "жара груди" - метафоры внутреннего беспокойства, гнева и негативных эмоций. Хадис подчеркивает непрерывность духовного состояния постящегося - даже во сне он остается в состоянии поклонения. Это указывает на то, что пост - это не просто воздержание от еды и питья, но целостное духовное состояние. Упоминание о двух радостях постящегося - при разговении и при встрече с Аллахом - показывает как временные, так и вечные плоды поста. Наконец, хадис связывает пост с контролем над страстями, особенно рекомендуя его молодым людям как средство духовной защиты и самодисциплины.''' }, { 'title': 'Пост в месяц Рамадан', 'text': 'عن أبي عبد الله عليه السلام قال: من صام شهر رمضان إيماناً واحتساباً غفر له ما تقدم من ذنبه.', 'translation': [ {'language_code': 'ru', 'title': 'От Абу Абдуллаха (мир ему): Кто постился в месяц Рамадан с верой и надеждой на награду, тому прощены его прошлые грехи.'}, {'language_code': 'fa', 'title': 'از امام صادق علیه السلام: هر کس ماه رمضان را با ایمان و امید به پاداش روزه بگیرد، گناهان گذشته‌اش آمرزیده می‌شود.'}, {'language_code': 'en', 'title': 'From Abu Abdullah: Whoever fasts the month of Ramadan with faith and hope for reward, his past sins are forgiven.'} ], 'explanation': 'Этот хадис говорит о великой награде за пост в месяц Рамадан.' } ], 'ethics': [ { 'title': 'Благородный нрав', 'text': 'قال رسول الله صلى الله عليه وآله: إنما بعثت لأتمم مكارم الأخلاق.', 'translation': [ {'language_code': 'ru', 'title': 'Сказал Посланник Аллаха (да благословит Аллах его и его семейство): Поистине, я послан, чтобы довести до совершенства благородные нравы.'}, {'language_code': 'fa', 'title': 'رسول خدا فرمود: من فقط برای تکمیل مکارم اخلاق مبعوث شده‌ام.'}, {'language_code': 'en', 'title': 'The Messenger of Allah said: I was sent only to perfect noble character.'} ], 'explanation': 'Этот хадис показывает важность нравственности в исламской религии.' }, { 'title': 'Терпение', 'text': 'عن أمير المؤمنين عليه السلام: الصبر صبران: صبر على ما تكره، وصبر عما تحب.', 'translation': [ {'language_code': 'ru', 'title': 'От Повелителя верующих (мир ему): Терпение бывает двух видов: терпение к тому, что ты не любишь, и терпение от того, что ты любишь.'}, {'language_code': 'fa', 'title': 'از امیرمؤمنان علیه السلام: صبر دو گونه است: صبر بر آنچه دوست نداری و صبر از آنچه دوست داری.'}, {'language_code': 'en', 'title': 'From Amir al-Muminin: Patience is of two types: patience with what you dislike, and patience from what you love.'} ], 'explanation': 'Этот хадис описывает виды терпения.' }, { 'title': 'Справедливость', 'text': 'قال رسول الله صلى الله عليه وآله: العدل أساس الملك.', 'translation': [ {'language_code': 'ru', 'title': 'Сказал Посланник Аллаха (да благословит Аллах его и его семейство): Справедливость - основа власти.'}, {'language_code': 'fa', 'title': 'رسول خدا فرمود: عدالت اساس حکومت است.'}, {'language_code': 'en', 'title': 'The Messenger of Allah said: Justice is the foundation of governance.'} ], 'explanation': 'Этот хадис подчеркивает важность справедливости в управлении.' }, { 'title': 'Знание', 'text': 'قال النبي صلى الله عليه وآله: اطلبوا العلم من المهد إلى اللحد.', 'translation': [ {'language_code': 'ru', 'title': 'Сказал Пророк (да благословит Аллах его и его семейство): Ищите знания от колыбели до могилы.'}, {'language_code': 'fa', 'title': 'پیامبر فرمود: علم را از گهواره تا گور بجویید.'}, {'language_code': 'en', 'title': 'The Prophet said: Seek knowledge from the cradle to the grave.'} ], 'explanation': 'Этот хадис призывает к постоянному поиску знаний на протяжении всей жизни.' } ], 'quran': [ { 'title': 'Достоинство чтения Корана', 'text': 'قال النبي صلى الله عليه وآله: اقرؤوا القرآن فإنه يأتي يوم القيامة شفيعاً لأصحابه.', 'translation': [ {'language_code': 'ru', 'title': 'Сказал Пророк (да благословит Аллах его и его семейство): Читайте Коран, ибо он придет в День Воскресения заступником за своих сподвижников.'}, {'language_code': 'fa', 'title': 'پیامبر فرمود: قرآن بخوانید که در روز قیامت شفیع اصحابش خواهد بود.'}, {'language_code': 'en', 'title': 'The Prophet said: Read the Quran, for it will come on the Day of Judgment as an intercessor for its companions.'} ], 'explanation': 'Этот хадис описывает достоинство чтения Священного Корана.' }, { 'title': 'Изучение Корана', 'text': 'عن أبي عبد الله عليه السلام قال: خيركم من تعلم القرآن وعلمه.', 'translation': [ {'language_code': 'ru', 'title': 'От Абу Абдуллаха (мир ему): Лучший из вас тот, кто изучает Коран и обучает ему.'}, {'language_code': 'fa', 'title': 'از امام صادق علیه السلام: بهترین شما کسی است که قرآن بیاموزد و آن را تعلیم دهد.'}, {'language_code': 'en', 'title': 'From Abu Abdullah: The best of you is the one who learns the Quran and teaches it.'} ], 'explanation': 'Этот хадис подчеркивает важность изучения и обучения Корану.' }, { 'title': 'Размышление над Кораном', 'text': 'قال أمير المؤمنين عليه السلام: تدبروا آيات القرآن واعتبروا به.', 'translation': [ {'language_code': 'ru', 'title': 'Сказал Повелитель верующих (мир ему): Размышляйте над аятами Корана и извлекайте из него уроки.'}, {'language_code': 'fa', 'title': 'امیرمؤمنان علیه السلام فرمود: در آیات قرآن تدبر کنید و از آن عبرت بگیرید.'}, {'language_code': 'en', 'title': 'Amir al-Muminin said: Contemplate the verses of the Quran and take lessons from it.'} ], 'explanation': 'Этот хадис призывает к глубокому размышлению над аятами Корана.' } ] } hadis_records = [] hadis_number = 1 # Batch processing for hadis creation hadis_to_create = [] hadis_to_update = [] hadis_tags_to_set = [] print("Processing categories in batches...") # Create hadis for each leaf category (10 hadis per category) total_categories = len(leaf_categories) for idx, category in enumerate(leaf_categories, 1): print(f" Processing category {idx}/{total_categories}: {category.title}") # Get existing hadis for this category to avoid duplicates existing_hadis = { h.number: h for h in Hadis.objects.filter(category=category) } # Determine hadis type based on category title hadis_type = 'ethics' # default if 'молитв' in category.title.lower() or 'намаз' in category.title.lower(): hadis_type = 'prayer' elif 'пост' in category.title.lower() or 'روزه' in category.title: hadis_type = 'fasting' elif 'нравственност' in category.title.lower() or 'اخلاق' in category.title: hadis_type = 'ethics' elif 'коран' in category.title.lower() or 'толкован' in category.title.lower(): hadis_type = 'quran' # Create exactly 10 hadis per leaf category available_samples = hadis_samples.get(hadis_type, hadis_samples['ethics']) for i in range(10): sample = random.choice(available_samples) # Generate varied links based on hadis type and number links = [] if hadis_type == 'prayer': links = [ {'title': 'Книги о молитве', 'link': f'https://islamicbooks.ru/prayer/{hadis_number}'}, {'title': 'Времена молитв', 'link': 'https://prayertimes.ru'}, {'title': 'Руководство по молитве', 'link': 'https://salah-guide.ru'} ] elif hadis_type == 'fasting': links = [ {'title': 'Книги о посте', 'link': f'https://islamicbooks.ru/fasting/{hadis_number}'}, {'title': 'Календарь поста', 'link': 'https://ramadan-calendar.ru'}, {'title': 'Правила поста', 'link': 'https://fasting-rules.ru'} ] elif hadis_type == 'quran': links = [ {'title': 'Толкование Корана', 'link': f'https://quran-tafsir.ru/hadis/{hadis_number}'}, {'title': 'Текст Корана', 'link': 'https://quran-text.ru'}, {'title': 'Аудио Коран', 'link': 'https://quran-audio.ru'} ] else: # ethics links = [ {'title': 'Исламская этика', 'link': f'https://islamic-ethics.ru/hadis/{hadis_number}'}, {'title': 'Нравственные учения', 'link': 'https://moral-teachings.ru'}, {'title': 'Духовное развитие', 'link': 'https://spiritual-growth.ru'} ] # Check if hadis already exists if hadis_number in existing_hadis: hadis = existing_hadis[hadis_number] # Check if update is needed updated = False if (hadis.title != sample['title'] or hadis.text != sample['text'] or hadis.translation != sample['translation'] or hadis.explanation != sample.get('explanation', '') or hadis.links != links): hadis.title = sample['title'] hadis.text = sample['text'] hadis.translation = sample['translation'] hadis.explanation = sample.get('explanation', '') hadis.links = links hadis_to_update.append(hadis) updated = True if updated: print(f" Will update hadis #{hadis.number}: {hadis.title}") else: print(f" Hadis #{hadis.number} already exists and is up to date") # Add tags if needed if not hadis.tags.exists(): selected_tags = random.sample(tags, random.randint(2, 5)) hadis_tags_to_set.append((hadis, selected_tags)) else: # Create new hadis hadis = Hadis( category=category, number=hadis_number, title=sample['title'], text=sample['text'], translation=sample['translation'], status=True, hadis_status=random.choice(statuses), hadis_status_text="Приведен в достоверных книгах", address=f"Книга {category.title}, хадис {hadis_number}", explanation=sample.get('explanation', ''), links=links ) hadis_to_create.append(hadis) # Prepare tags for later assignment selected_tags = random.sample(tags, random.randint(2, 5)) hadis_tags_to_set.append((hadis, selected_tags)) print(f" Will create hadis #{hadis_number}: {hadis.title}") hadis_records.append(hadis) hadis_number += 1 # Batch operations every 50 hadis or at end of category if len(hadis_to_create) >= 50 or len(hadis_to_update) >= 50: self._perform_hadis_batch_operations(hadis_to_create, hadis_to_update, hadis_tags_to_set) hadis_to_create = [] hadis_to_update = [] hadis_tags_to_set = [] # Final batch operations if hadis_to_create or hadis_to_update: self._perform_hadis_batch_operations(hadis_to_create, hadis_to_update, hadis_tags_to_set) return hadis_records def _perform_hadis_batch_operations(self, hadis_to_create, hadis_to_update, hadis_tags_to_set): """Perform batch database operations for hadis""" # Batch create if hadis_to_create: Hadis.objects.bulk_create(hadis_to_create, ignore_conflicts=True) print(f" Batch created {len(hadis_to_create)} hadis records") # Batch update if hadis_to_update: Hadis.objects.bulk_update( hadis_to_update, ['title', 'text', 'translation', 'explanation', 'links'] ) print(f" Batch updated {len(hadis_to_update)} hadis records") # Set tags (this needs to be done after creation/update) if hadis_tags_to_set: for hadis, tags_list in hadis_tags_to_set: # For newly created hadis, we need to get the actual object from DB if not hadis.pk: try: hadis = Hadis.objects.get(category=hadis.category, number=hadis.number) except Hadis.DoesNotExist: continue hadis.tags.set(tags_list) print(f" Set tags for {len(hadis_tags_to_set)} hadis records") def seed_hadis_transmitters(self, hadis_records, transmitters, statuses): """Create HadisTransmitter records (transmission chains) - optimized batch creation""" print("Creating Hadis Transmitters (chains)...") transmitter_chains = [] chains_to_create = [] # Get hadis that already have transmitters to avoid duplicates hadis_with_transmitters = set( HadisTransmitter.objects.values_list('hadis_id', flat=True).distinct() ) print(f"Processing {len(hadis_records)} hadis records...") for hadis in hadis_records: # Skip if this hadis already has transmitters if hadis.id in hadis_with_transmitters: print(f" Hadis #{hadis.number} already has transmitters, skipping...") continue # Create a transmission chain of 3-6 transmitters chain_length = random.randint(3, 6) selected_transmitters = random.sample(transmitters, min(chain_length, len(transmitters))) for order, transmitter in enumerate(selected_transmitters, 1): # Occasionally create gaps in the chain is_gap = random.choice([False, False, False, True]) # 25% chance of gap chain = HadisTransmitter( hadis=hadis, order=order, transmitter=transmitter if not is_gap else None, status=random.choice(statuses), is_gap=is_gap ) chains_to_create.append(chain) transmitter_chains.append(chain) if is_gap: print(f" Will add gap in chain for hadis #{hadis.number} at position {order}") else: print(f" Will add transmitter {transmitter.full_name} to hadis #{hadis.number}") # Batch create every 100 chains if len(chains_to_create) >= 100: HadisTransmitter.objects.bulk_create(chains_to_create, ignore_conflicts=True) print(f" Batch created {len(chains_to_create)} transmitter chains") chains_to_create = [] # Final batch create if chains_to_create: HadisTransmitter.objects.bulk_create(chains_to_create, ignore_conflicts=True) print(f" Final batch created {len(chains_to_create)} transmitter chains") return transmitter_chains def seed_hadis_references(self, hadis_records, books): """Create HadisReference records - optimized batch creation""" print("Creating Hadis References...") references = [] references_to_create = [] references_to_update = [] # Get existing references to avoid duplicates existing_references = {} for ref in HadisReference.objects.select_related('hadis', 'book').all(): key = (ref.hadis_id, ref.book_id) existing_references[key] = ref print(f"Processing references for {len(hadis_records)} hadis records...") for hadis in hadis_records: # Each hadis can have 1-3 references num_refs = random.randint(1, 3) selected_books = random.sample(books, min(num_refs, len(books))) for book in selected_books: key = (hadis.id, book.id) new_description = f"Источник хадиса номер {hadis.number} в книге {book.title}" if key in existing_references: reference = existing_references[key] if reference.description != new_description: reference.description = new_description references_to_update.append(reference) print(f" Will update reference: Hadis #{hadis.number} -> {book.title}") else: print(f" Reference already exists: Hadis #{hadis.number} -> {book.title}") else: reference = HadisReference( hadis=hadis, book=book, description=new_description ) references_to_create.append(reference) print(f" Will create reference: Hadis #{hadis.number} -> {book.title}") references.append(reference) # Batch operations every 100 references if len(references_to_create) >= 100: HadisReference.objects.bulk_create(references_to_create, ignore_conflicts=True) print(f" Batch created {len(references_to_create)} references") references_to_create = [] if len(references_to_update) >= 100: HadisReference.objects.bulk_update(references_to_update, ['description']) print(f" Batch updated {len(references_to_update)} references") references_to_update = [] # Final batch operations if references_to_create: HadisReference.objects.bulk_create(references_to_create, ignore_conflicts=True) print(f" Final batch created {len(references_to_create)} references") if references_to_update: HadisReference.objects.bulk_update(references_to_update, ['description']) print(f" Final batch updated {len(references_to_update)} references") return references def seed_reference_images(self, references): """Create ReferenceImage records""" print("Creating Reference Images...") reference_images = [] for reference in references: # 50% chance to add images to reference if random.choice([True, False]): # Add 1-2 images per reference num_images = random.randint(1, 2) for i in range(num_images): image_file = random.choice(self.image_files) ref_image = ReferenceImage.objects.create( reference=reference, priority=i ) try: with open(image_file, 'rb') as f: ref_image.thumbnail.save( f"ref_image_{ref_image.id}.png", File(f), save=True ) reference_images.append(ref_image) print(f" Added image to reference: {reference.hadis.title}") except Exception as e: print(f" Warning: Could not add image to reference: {e}") ref_image.delete() return reference_images @transaction.atomic def run_seeding(self, clear_existing=False): """Main method to run all seeding operations""" print("=" * 60) print("STARTING HADIS DATA SEEDING") print("=" * 60) try: if clear_existing: self.clear_existing_data() # Step 1: Create basic lookup data print("\n" + "=" * 40) print("STEP 1: Creating basic lookup data") print("=" * 40) statuses = self.seed_hadis_statuses() tags = self.seed_hadis_tags() sects = self.seed_hadis_sects() # Step 2: Create hierarchical categories print("\n" + "=" * 40) print("STEP 2: Creating hierarchical categories") print("=" * 40) categories = self.seed_hadis_categories(sects) # Step 3: Create library data for references print("\n" + "=" * 40) print("STEP 3: Creating library data") print("=" * 40) books, _, _ = self.seed_library_data() # Step 4: Create transmitters print("\n" + "=" * 40) print("STEP 4: Creating transmitters") print("=" * 40) transmitters = self.seed_transmitters() # Step 5: Create hadis records print("\n" + "=" * 40) print("STEP 5: Creating hadis records") print("=" * 40) hadis_records = self.seed_hadis_records(categories, statuses, tags, transmitters, books) # Step 6: Create transmission chains print("\n" + "=" * 40) print("STEP 6: Creating transmission chains") print("=" * 40) transmitter_chains = self.seed_hadis_transmitters(hadis_records, transmitters, statuses) # Step 7: Create references print("\n" + "=" * 40) print("STEP 7: Creating references") print("=" * 40) references = self.seed_hadis_references(hadis_records, books) # Step 8: Create reference images print("\n" + "=" * 40) print("STEP 8: Creating reference images") print("=" * 40) reference_images = self.seed_reference_images(references) # Summary print("\n" + "=" * 60) print("SEEDING COMPLETED SUCCESSFULLY!") print("=" * 60) print(f"Created:") print(f" - {len(sects)} Hadis Sects") print(f" - {len(categories)} Hadis Categories") print(f" - {len(statuses)} Hadis Statuses") print(f" - {len(tags)} Hadis Tags") print(f" - {len(transmitters)} Transmitters") print(f" - {len(hadis_records)} Hadis Records") print(f" - {len(transmitter_chains)} Transmitter Chain Links") print(f" - {len(books)} Books") print(f" - {len(references)} Hadis References") print(f" - {len(reference_images)} Reference Images") print("=" * 60) return { 'sects': sects, 'categories': categories, 'statuses': statuses, 'tags': tags, 'transmitters': transmitters, 'hadis_records': hadis_records, 'transmitter_chains': transmitter_chains, 'books': books, 'references': references, 'reference_images': reference_images } except Exception as e: print(f"\nERROR during seeding: {e}") print("Rolling back transaction...") raise def main(): """Main function to run the seeding script""" import argparse parser = argparse.ArgumentParser(description='Seed Hadis app with sample data') parser.add_argument( '--clear', action='store_true', help='Clear existing data before seeding' ) parser.add_argument( '--no-clear', action='store_true', help='Do not clear existing data (default)' ) args = parser.parse_args() # Default to not clearing unless explicitly requested clear_existing = args.clear and not args.no_clear if clear_existing: response = input("This will DELETE all existing Hadis data. Are you sure? (yes/no): ") if response.lower() != 'yes': print("Seeding cancelled.") return try: seeder = HadisDataSeeder() seeder.run_seeding(clear_existing=clear_existing) print("\n✅ Seeding completed successfully!") print("You can now test the APIs:") print(" - GET /api/hadis/sects/") print(" - GET /api/hadis/sect/{sect_id}/categories/") print(" - GET /api/hadis/category/{category_id}/hadis/") except Exception as e: print(f"\n❌ Seeding failed: {e}") import traceback traceback.print_exc() sys.exit(1) if __name__ == '__main__': main()