You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

139 lines
9.2 KiB

# Generated by Django 4.2.30 on 2026-09-15 11:45
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
('profiles', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Post',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255, verbose_name='Post Title')),
('slug', models.SlugField(allow_unicode=True, blank=True, max_length=255, null=True, unique=True, verbose_name='Slug / URL Identifier')),
('post_type', models.CharField(choices=[('news', 'News & Announcements'), ('article', 'Analytical Article'), ('report', 'Field & Diplomatic Report'), ('interview', 'Expert Interview')], default='article', max_length=50, verbose_name='Post Type')),
('language', models.CharField(choices=[('fa', 'Persian'), ('ar', 'Arabic'), ('en', 'English'), ('ur', 'Urdu'), ('fr', 'French')], default='en', max_length=10, verbose_name='Language')),
('status', models.CharField(choices=[('draft', 'Draft'), ('review', 'Under Review'), ('published', 'Published'), ('archived', 'Archived')], default='published', max_length=20, verbose_name='Publication Status')),
('author_role_label', models.CharField(blank=True, help_text='e.g. Senior Researcher, Center Director, Diplomatic Envoy', max_length=150, null=True, verbose_name='Author Role Label')),
('author_custom_avatar', models.ImageField(blank=True, null=True, upload_to='cms/avatars/%Y/%m/', verbose_name='Custom Author Avatar')),
('featured_image', models.ImageField(blank=True, null=True, upload_to='cms/featured/%Y/%m/', verbose_name='Featured Cover Image')),
('excerpt', models.TextField(blank=True, help_text='Brief summary for search results and cards.', null=True, verbose_name='Excerpt / Summary')),
('content', models.TextField(verbose_name='Rich Text / Markdown Content')),
('tags', models.JSONField(blank=True, default=list, verbose_name='Tags')),
('reading_time_minutes', models.PositiveIntegerField(default=3, verbose_name='Reading Time (Minutes)')),
('views_count', models.PositiveIntegerField(default=0, verbose_name='Views Count')),
('likes_count', models.PositiveIntegerField(default=0, verbose_name='Likes Count')),
('is_featured', models.BooleanField(default=False, verbose_name='Is Featured')),
('publish_date', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Publish Date')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cms_posts', to=settings.AUTH_USER_MODEL, verbose_name='Author')),
],
options={
'verbose_name': 'Post',
'verbose_name_plural': 'Posts',
'ordering': ('-is_featured', '-publish_date'),
},
),
migrations.CreateModel(
name='PostCategory',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='Category Name')),
('slug', models.SlugField(allow_unicode=True, max_length=255, unique=True, verbose_name='Slug / URL Identifier')),
('language', models.CharField(choices=[('fa', 'Persian'), ('en', 'English'), ('ar', 'Arabic'), ('ur', 'Urdu'), ('ru', 'Russian')], default='en', max_length=10, verbose_name='Language')),
('description', models.TextField(blank=True, null=True, verbose_name='Category Description')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')),
],
options={
'verbose_name': 'Post Category',
'verbose_name_plural': 'Post Categories',
'ordering': ('name',),
},
),
migrations.CreateModel(
name='PostTag',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100, unique=True, verbose_name='Tag Name')),
('slug', models.SlugField(allow_unicode=True, max_length=100, unique=True, verbose_name='Slug')),
],
options={
'verbose_name': 'Post Tag',
'verbose_name_plural': 'Post Tags',
'ordering': ('name',),
},
),
migrations.CreateModel(
name='PostComment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('author_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Author Name')),
('author_email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='Author Email')),
('content', models.TextField(verbose_name='Comment Content')),
('status', models.CharField(choices=[('pending', 'Pending Moderation'), ('approved', 'Approved'), ('spam', 'Spam / Rejected')], default='approved', max_length=20, verbose_name='Moderation Status')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')),
('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='cms.post', verbose_name='Post')),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='post_comments', to=settings.AUTH_USER_MODEL, verbose_name='User')),
],
options={
'verbose_name': 'Post Comment',
'verbose_name_plural': 'Post Comments',
'ordering': ('-created_at',),
},
),
migrations.AddField(
model_name='post',
name='category',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='posts', to='cms.postcategory', verbose_name='Category'),
),
migrations.AddField(
model_name='post',
name='institution',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='cms_posts', to='profiles.institution', verbose_name='Associated Institution'),
),
migrations.CreateModel(
name='MediaAsset',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.FileField(upload_to='cms/media/%Y/%m/', verbose_name='Media File')),
('title', models.CharField(blank=True, max_length=255, null=True, verbose_name='Title / Description')),
('media_type', models.CharField(choices=[('image', 'Image'), ('video', 'Video'), ('audio', 'Audio'), ('document', 'Document / PDF')], default='image', max_length=20, verbose_name='Media Type')),
('file_size', models.PositiveIntegerField(default=0, verbose_name='File Size (Bytes)')),
('dimensions', models.CharField(blank=True, max_length=50, null=True, verbose_name='Dimensions (WxH)')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')),
('uploaded_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='uploaded_cms_media', to=settings.AUTH_USER_MODEL, verbose_name='Uploaded By')),
],
options={
'verbose_name': 'Media Asset',
'verbose_name_plural': 'Media Asset Library',
'ordering': ('-created_at',),
},
),
migrations.CreateModel(
name='PostLike',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')),
('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='likes', to='cms.post', verbose_name='Post')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cms_post_likes', to=settings.AUTH_USER_MODEL, verbose_name='User')),
],
options={
'verbose_name': 'Post Like',
'verbose_name_plural': 'Post Likes',
'ordering': ('-created_at',),
'unique_together': {('post', 'user')},
},
),
]