diff --git a/apps/article/management/commands/populate_article.py b/apps/article/management/commands/populate_article.py new file mode 100644 index 0000000..f30ca34 --- /dev/null +++ b/apps/article/management/commands/populate_article.py @@ -0,0 +1,123 @@ +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!')) \ No newline at end of file diff --git a/seeds/images/articl2.jpg b/seeds/images/articl2.jpg new file mode 100644 index 0000000..07c36c5 Binary files /dev/null and b/seeds/images/articl2.jpg differ diff --git a/seeds/images/articl3.jpg b/seeds/images/articl3.jpg new file mode 100644 index 0000000..bafb6a1 Binary files /dev/null and b/seeds/images/articl3.jpg differ diff --git a/seeds/images/articl4.jpg b/seeds/images/articl4.jpg new file mode 100644 index 0000000..edfeeed Binary files /dev/null and b/seeds/images/articl4.jpg differ