import os import random from django.core.management.base import BaseCommand from django.core.files import File from django.conf import settings from django.db import transaction # REPLACE 'apps.article.models' WITH YOUR ACTUAL APP PATH from apps.article.models import ( Article, ArticleCategory, ArticleCollection, ArticleInCollection, ArticleContent, ContentPart, TextSection ) class Command(BaseCommand): help = 'Seeds 25 articles with categories, collections, and structured content.' def handle(self, *args, **kwargs): self.stdout.write('Seeding Articles...') # 1. Configuration TOTAL_ARTICLES = 25 CATEGORY_IDS = [6, 7, 8, 9] CONTENT_SOURCE_IDS = range(13, 24) # IDs 13 to 23 IMAGE_DIR = os.path.join(settings.BASE_DIR, 'seeds', 'images') IMAGE_NAMES = [f'articl{i}.jpg' for i in range(2, 5)] # 2. Fetch Existing Dependencies categories = list(ArticleCategory.objects.filter(id__in=CATEGORY_IDS)) if not categories: self.stdout.write(self.style.WARNING(f"Categories with IDs {CATEGORY_IDS} not found. Skipping category assignment.")) # 3. Create 4 New Collections collections = [] for i in range(1, 5): col, created = ArticleCollection.objects.get_or_create( title=f'Seeded Collection {i}', defaults={ 'slug': f'seeded-collection-{i}', 'summary': f'This is a generated summary for collection {i}', 'display_position': ArticleCollection.DisplayPosition.MIDDLE } ) collections.append(col) self.stdout.write(self.style.SUCCESS(f'Created/Loaded {len(collections)} collections.')) # 4. Fetch Source Content for Cloning # NOTE: Since ArticleContent is a ForeignKey (One-to-Many), we cannot # link existing content objects to new articles without removing them # from their old articles. Instead, we will CLONE their data. source_contents = list(ArticleContent.objects.filter(id__in=CONTENT_SOURCE_IDS)) if not source_contents: self.stdout.write(self.style.WARNING(f"ArticleContents with IDs 13-23 not found. Creating generic content instead.")) # 5. Main Loop: Create Articles with transaction.atomic(): for i in range(1, TOTAL_ARTICLES + 1): title = f'Seeded Article Title {i}' # Create Article article = Article.objects.create( title=title, description=f'Description for article {i}. Lorem ipsum dolor sit amet.', content=f'Full content body for article {i}.', status=True ) # Assign Thumbnail (Cycle through images 1-5) img_name = IMAGE_NAMES[(i - 1) % len(IMAGE_NAMES)] img_path = os.path.join(IMAGE_DIR, img_name) if os.path.exists(img_path): with open(img_path, 'rb') as f: article.thumbnail.save(img_name, File(f), save=True) else: self.stdout.write(self.style.WARNING(f"Image not found at {img_path}")) # Assign Categories (Randomly pick 1 or 2) if categories: article.categories.add(*random.sample(categories, k=random.randint(1, 2))) # Assign to Collections (Randomly pick 1) random_col = random.choice(collections) ArticleInCollection.objects.create( article=article, collection=random_col, order=i ) # Create Article Content (Cloning from IDs 13-23 or Generic) if source_contents: # Pick a random template from the requested IDs template = random.choice(source_contents) content_title = f"{template.title} (Copy for Article {i})" content_body = template.content else: content_title = f"Structured Content for Article {i}" content_body = "This is a section of structured content." # Create the ArticleContent object linked to this NEW article ac = ArticleContent.objects.create( article=article, title=content_title, content=content_body, priority=1 ) # Create nested ContentParts and TextSections part = ContentPart.objects.create(article_content=ac, order=1) TextSection.objects.create( content_part=part, arabic_text="نص تجريبي باللغة العربية", translation="Experimental text in English translation", order=1 ) self.stdout.write(f'Created Article: {article.title}') self.stdout.write(self.style.SUCCESS(f'Successfully seeded {TOTAL_ARTICLES} articles!'))