Refactor content handling in GenerateContentFunction and update related models and serializers

- Enhanced GenerateContentFunction to save content in a dedicated Content model, separating it from the Tasks model.
- Updated Tasks model to remove SEO-related fields, now managed in the Content model.
- Modified TasksSerializer to include new content fields and adjusted the API to reflect these changes.
- Improved the auto_generate_content_task method to utilize the new save_output method for better content management.
- Updated frontend components to display new content structure and metadata effectively.
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-10 14:06:15 +00:00
parent 8bb4c5d016
commit 8b6e18649c
11 changed files with 596 additions and 356 deletions

View File

@@ -0,0 +1,171 @@
from django.db import migrations, models
def _normalize_list(value):
if not value:
return []
if isinstance(value, list):
return value
if isinstance(value, tuple):
return list(value)
return [value]
def forwards(apps, schema_editor):
Tasks = apps.get_model('writer', 'Tasks')
Content = apps.get_model('writer', 'Content')
for task in Tasks.objects.all():
account_id = getattr(task, 'account_id', None)
if account_id is None and getattr(task, 'account', None):
account_id = task.account.id
site_id = getattr(task, 'site_id', None)
if site_id is None and getattr(task, 'site', None):
site_id = task.site.id
sector_id = getattr(task, 'sector_id', None)
if sector_id is None and getattr(task, 'sector', None):
sector_id = task.sector.id if task.sector else None
tenant_id = getattr(task, 'tenant_id', None)
if tenant_id is None and getattr(task, 'tenant', None):
tenant_id = task.tenant.id
# Prepare defaults for new content record
defaults = {
'html_content': task.content or '',
'word_count': task.word_count or 0,
'title': getattr(task, 'title', None),
'meta_title': getattr(task, 'meta_title', None),
'meta_description': getattr(task, 'meta_description', None),
'primary_keyword': getattr(task, 'primary_keyword', None),
'secondary_keywords': _normalize_list(getattr(task, 'secondary_keywords', [])),
'tags': _normalize_list(getattr(task, 'tags', [])),
'categories': _normalize_list(getattr(task, 'categories', [])),
'status': 'draft',
}
content_record = Content.objects.filter(task_id=task.id).first()
created = False
if not content_record:
content_record = Content(task_id=task.id, **defaults)
created = True
# Update existing records with the latest information
if not created:
if task.content:
content_record.html_content = task.content
if task.word_count:
content_record.word_count = task.word_count
if getattr(task, 'title', None):
content_record.title = task.title
if getattr(task, 'meta_title', None):
content_record.meta_title = task.meta_title
if getattr(task, 'meta_description', None):
content_record.meta_description = task.meta_description
if hasattr(task, 'primary_keyword'):
content_record.primary_keyword = task.primary_keyword or ''
if hasattr(task, 'secondary_keywords'):
content_record.secondary_keywords = _normalize_list(task.secondary_keywords)
if hasattr(task, 'tags'):
content_record.tags = _normalize_list(task.tags)
if hasattr(task, 'categories'):
content_record.categories = _normalize_list(task.categories)
if not content_record.status:
content_record.status = 'draft'
# Ensure account/site/sector alignment (save() will also set this)
if account_id:
content_record.account_id = account_id
if site_id:
content_record.site_id = site_id
if sector_id:
content_record.sector_id = sector_id
if tenant_id:
content_record.tenant_id = tenant_id
# Preserve existing metadata but ensure it's a dict
metadata = content_record.metadata or {}
content_record.metadata = metadata
content_record.save()
def backwards(apps, schema_editor):
"""
Reverse data migration is intentionally left as a no-op because
reverting would require reintroducing the removed fields on Tasks.
"""
pass
class Migration(migrations.Migration):
dependencies = [
('writer', '0004_add_content_seo_fields'),
]
operations = [
migrations.AddField(
model_name='content',
name='categories',
field=models.JSONField(blank=True, default=list, help_text='List of categories'),
),
migrations.AddField(
model_name='content',
name='meta_description',
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name='content',
name='meta_title',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='content',
name='primary_keyword',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='content',
name='secondary_keywords',
field=models.JSONField(blank=True, default=list, help_text='List of secondary keywords'),
),
migrations.AddField(
model_name='content',
name='status',
field=models.CharField(default='draft', help_text='Content workflow status (draft, review, published, etc.)', max_length=50),
),
migrations.AddField(
model_name='content',
name='tags',
field=models.JSONField(blank=True, default=list, help_text='List of tags'),
),
migrations.AddField(
model_name='content',
name='title',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.RunPython(forwards, backwards),
migrations.RemoveField(
model_name='tasks',
name='categories',
),
migrations.RemoveField(
model_name='tasks',
name='primary_keyword',
),
migrations.RemoveField(
model_name='tasks',
name='secondary_keywords',
),
migrations.RemoveField(
model_name='tasks',
name='tags',
),
]