from django.contrib.admin.models import CHANGE, LogEntry from django.contrib.contenttypes.models import ContentType from django.core.management.base import BaseCommand from django.db import DEFAULT_DB_ALIAS, connections, transaction from apps.content.current import AboutContent, AboutItem, HomeContent, ListingContent, SiteContent SITE_MOCK = { "official_name": "نام انجمن نمونه", "short_name": "انجمن نمونه", "faculty_subline": "دانشکده نمونه", "description": "این متن نمونه است و پس از ورود محتوای اصلی از پنل مدیریت جایگزین می‌شود.", "logo": "", "logo_alt": "", "nav_home": "خانه", "nav_about": "درباره ما", "nav_events": "رویدادها", "nav_blog": "بلاگ", "email": "contact@example.invalid", "phone": "0000000000", "telegram_url": "https://example.invalid/telegram", "instagram_url": "https://example.invalid/instagram", "website_url": "https://example.invalid", "address": "نشانی نمونه", "footer_copy": "متن نمونه پابرگ؛ محتوای نهایی را از پنل مدیریت وارد کنید.", "seo_title": "عنوان نمونه سایت", "seo_description": "توضیحات نمونه برای موتورهای جست‌وجو.", "seo_image": "", "seo_image_alt": "", } HOME_MOCK = { "title": "عنوان نمونه صفحه اصلی", "intro": "این متن نمونه صفحه اصلی است و پس از ورود محتوای اصلی جایگزین می‌شود.", "hero_heading": "عنوان نمونه صفحه اصلی", "hero_body": "توضیحات نمونه برای معرفی انجمن و فعالیت‌های آن.", "hero_image": "", "hero_image_alt": "", "hero_action_label": "مشاهده نمونه‌ها", "featured_events_heading": "رویدادهای نمونه", "featured_events_intro": "توضیحات نمونه برای بخش رویدادها.", "featured_events_link_label": "همه رویدادها", "featured_posts_heading": "نوشته‌های نمونه", "featured_posts_intro": "توضیحات نمونه برای بخش نوشته‌ها.", "featured_posts_link_label": "همه نوشته‌ها", "participation_heading": "به ما بپیوندید", "participation_body": "این متن نمونه راه‌های مشارکت را توضیح می‌دهد.", "participation_image": "", "participation_image_alt": "", "participation_action_label": "اطلاعات بیشتر", "seo_title": "عنوان نمونه صفحه اصلی", "seo_description": "توضیحات نمونه صفحه اصلی برای موتورهای جست‌وجو.", "seo_image": "", "seo_image_alt": "", } ABOUT_MOCK = { "title": "عنوان نمونه صفحه درباره ما", "intro": "این متن نمونه معرفی انجمن است و بعداً از پنل مدیریت قابل ویرایش است.", "identity_heading": "معرفی نمونه", "identity_body": "اطلاعات نمونه درباره هویت انجمن.", "mission_heading": "ماموریت نمونه", "mission_body": "توضیحات نمونه درباره ماموریت انجمن.", "activities_heading": "فعالیت‌های نمونه", "activities_body": "توضیحات نمونه درباره فعالیت‌ها.", "values_heading": "ارزش‌های نمونه", "values_body": "یادگیری، همکاری و مسئولیت‌پذیری نمونه.", "committees_heading": "کمیته‌های نمونه", "committees_body": "اطلاعات نمونه درباره کمیته‌ها.", "affiliations_heading": "همکاری‌های نمونه", "affiliations_body": "اطلاعات نمونه درباره گروه‌های همکار.", "faq_heading": "پرسش‌های نمونه", "contact_heading": "راه‌های ارتباطی نمونه", "seo_title": "عنوان نمونه صفحه درباره ما", "seo_description": "توضیحات نمونه صفحه درباره ما برای موتورهای جست‌وجو.", "seo_image": "", "seo_image_alt": "", } LISTING_MOCKS = { "events": { "title": "عنوان نمونه رویدادها", "intro": "این متن نمونه برای معرفی فهرست رویدادهاست.", "seo_title": "عنوان نمونه رویدادها", "seo_description": "توضیحات نمونه صفحه رویدادها برای موتورهای جست‌وجو.", "seo_image": "", "seo_image_alt": "", }, "blog": { "title": "عنوان نمونه بلاگ", "intro": "این متن نمونه برای معرفی نوشته‌های بلاگ است.", "seo_title": "عنوان نمونه بلاگ", "seo_description": "توضیحات نمونه صفحه بلاگ برای موتورهای جست‌وجو.", "seo_image": "", "seo_image_alt": "", }, } ABOUT_ITEM_MOCKS = ( ("mission", "ماموریت نمونه", "این متن نمونه برای توضیح ماموریت انجمن است."), ("activities", "فعالیت نمونه", "این متن نمونه یکی از فعالیت‌های انجمن را معرفی می‌کند."), ("values", "ارزش نمونه", "این متن نمونه یکی از ارزش‌های انجمن را توضیح می‌دهد."), ("committees", "کمیته نمونه", "این متن نمونه برای معرفی یک کمیته است."), ("affiliations", "همکاری نمونه", "این متن نمونه برای معرفی یک گروه همکار است."), ("faq", "پرسش نمونه", "پاسخ نمونه؛ اطلاعات نهایی را از پنل مدیریت وارد کنید."), ) RECORDS = ( ("site", SiteContent, {"pk": 1}, SITE_MOCK), ("home", HomeContent, {"pk": 1}, HOME_MOCK), ("about", AboutContent, {"pk": 1}, ABOUT_MOCK), ("events", ListingContent, {"pk": "events"}, LISTING_MOCKS["events"]), ("blog", ListingContent, {"pk": "blog"}, LISTING_MOCKS["blog"]), ) def has_admin_change(model, object_id, using): content_type = ContentType.objects.db_manager(using).get_for_model(model) return LogEntry.objects.using(using).filter( content_type=content_type, object_id=str(object_id), action_flag=CHANGE, ).exists() class Command(BaseCommand): help = "Fill untouched site content records with obvious sample copy." def add_arguments(self, parser): parser.add_argument( "--database", default=DEFAULT_DB_ALIAS, choices=tuple(connections), help="Database alias to update.", ) parser.add_argument( "--dry-run", action="store_true", help="Report intended changes without writing to the database.", ) def handle(self, *args, database, dry_run, **options): updated = 0 skipped = 0 prefix = "Dry run: " if dry_run else "" with transaction.atomic(using=database): for label, model, lookup, values in RECORDS: record = model.objects.using(database).select_for_update().filter(**lookup).first() object_id = lookup["pk"] if record is not None and has_admin_change(model, object_id, database): self.stdout.write(f"Skipped {label}: it has a Django admin change entry.") skipped += 1 continue if dry_run: action = "create" if record is None else "replace" self.stdout.write(f"Dry run: would {action} {label} with mock content.") updated += 1 continue if record is None: record = model(**lookup) for field, value in values.items(): setattr(record, field, value) record.save(using=database) updated += 1 self.stdout.write(f"Loaded mock content for {label}.") if label == "about": AboutItem.objects.using(database).filter(about_id=record.pk).delete() AboutItem.objects.using(database).bulk_create( [ AboutItem(about_id=record.pk, kind=kind, title=title, text=text, position=position) for position, (kind, title, text) in enumerate(ABOUT_ITEM_MOCKS) ] ) action = "would be updated" if dry_run else "updated" summary = f"{updated} content records {action}; {skipped} admin-edited records skipped." self.stdout.write(f"{prefix}{summary}")