| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- from __future__ import annotations
- from django.core.management.base import BaseCommand
- import os
- from pathlib import Path
- from django.conf import settings
- from django.core.files import File
- from cms.models import create_demo_data, PostCategory, Post
- from orgs.models import Organization
- class Command(BaseCommand):
- help = "Seed demo categories and posts for the CMS app (optionally per organization)"
- def handle(self, *args, **options):
- org_ident = options.get("org")
- org = None
- if org_ident:
- if org_ident.isdigit():
- org = Organization.objects.filter(pk=int(org_ident)).first()
- if org is None:
- org = Organization.objects.filter(code=org_ident).first() or Organization.objects.filter(name=org_ident).first()
- if org is None:
- raise SystemExit(self.style.ERROR(f"Organization not found: {org_ident}"))
- # Ensure root category per org if org is provided
- if org is not None:
- root_name = f"{org.code}_root"
- root_slug = f"{org.code}-root"
- root, _ = PostCategory.objects.get_or_create(
- organization=org,
- slug=root_slug,
- defaults={
- "name": root_name,
- "parent": None,
- "description": f"Root category for {org.code}",
- },
- )
- result = create_demo_data(org=org)
- # Move all top-level categories under the root (excluding the root itself)
- if org is not None:
- # Re-fetch root to be safe
- root = PostCategory.objects.get(organization=org, slug=f"{org.code}-root")
- top_levels = PostCategory.objects.filter(organization=org, parent__isnull=True).exclude(pk=root.pk)
- for cat in top_levels:
- cat.parent = root
- cat.save()
- # Attach demo feature images from static/demo/ if available
- try:
- demo_dir = Path(settings.BASE_DIR) / "static" / "demo"
- if demo_dir.exists() and demo_dir.is_dir():
- image_files = [p for p in sorted(demo_dir.iterdir()) if p.suffix.lower() in {".jpg", ".jpeg", ".png", ".webp", ".gif"}]
- else:
- image_files = []
- except Exception:
- image_files = []
- if image_files:
- posts_qs = Post.objects.all().order_by("id")
- if org is not None:
- posts_qs = posts_qs.filter(organization=org)
- idx = 0
- for post in posts_qs:
- if not getattr(post, "feature_image", None) or not post.feature_image:
- img_path = image_files[idx % len(image_files)]
- try:
- with open(img_path, "rb") as fh:
- post.feature_image.save(img_path.name, File(fh), save=True)
- except Exception:
- # Skip on any IO error and continue with next
- pass
- idx += 1
- suffix = f" for org {org.code}" if org else ""
- self.stdout.write(self.style.SUCCESS(
- f"CMS demo data seeded{suffix}: categories={result.get('categories', 0)}, posts={result.get('posts', 0)}"
- ))
- def add_arguments(self, parser):
- parser.add_argument("--org", help="Organization code, id, or name to seed CMS data for", default=None)
|