from rest_framework import serializers from .models import Keywords, Clusters, ContentIdeas from igny8_core.auth.models import SeedKeyword from igny8_core.auth.serializers import SeedKeywordSerializer class KeywordSerializer(serializers.ModelSerializer): """Serializer for Keywords model with SeedKeyword relationship""" # Read-only properties from seed_keyword keyword = serializers.CharField(read_only=True) # From seed_keyword.keyword volume = serializers.IntegerField(read_only=True) # From seed_keyword.volume or volume_override difficulty = serializers.IntegerField(read_only=True) # From seed_keyword.difficulty or difficulty_override intent = serializers.CharField(read_only=True) # From seed_keyword.intent # SeedKeyword relationship seed_keyword_id = serializers.IntegerField(write_only=True, required=True) seed_keyword = SeedKeywordSerializer(read_only=True) # Overrides volume_override = serializers.IntegerField(required=False, allow_null=True) difficulty_override = serializers.IntegerField(required=False, allow_null=True) # Related fields cluster_name = serializers.SerializerMethodField() sector_name = serializers.SerializerMethodField() site_id = serializers.IntegerField(write_only=True, required=False) sector_id = serializers.IntegerField(write_only=True, required=False) class Meta: model = Keywords fields = [ 'id', 'seed_keyword_id', 'seed_keyword', 'keyword', 'volume', 'difficulty', 'intent', 'volume_override', 'difficulty_override', 'cluster_id', 'cluster_name', 'sector_name', 'status', 'created_at', 'updated_at', 'site_id', 'sector_id', 'account_id', ] read_only_fields = ['id', 'created_at', 'updated_at', 'account_id', 'keyword', 'volume', 'difficulty', 'intent'] def create(self, validated_data): """Create Keywords instance with seed_keyword""" seed_keyword_id = validated_data.pop('seed_keyword_id') try: seed_keyword = SeedKeyword.objects.get(id=seed_keyword_id) except SeedKeyword.DoesNotExist: raise serializers.ValidationError({'seed_keyword_id': f'SeedKeyword with id {seed_keyword_id} does not exist'}) validated_data['seed_keyword'] = seed_keyword return super().create(validated_data) def update(self, instance, validated_data): """Update Keywords instance with seed_keyword""" if 'seed_keyword_id' in validated_data: seed_keyword_id = validated_data.pop('seed_keyword_id') try: seed_keyword = SeedKeyword.objects.get(id=seed_keyword_id) validated_data['seed_keyword'] = seed_keyword except SeedKeyword.DoesNotExist: raise serializers.ValidationError({'seed_keyword_id': f'SeedKeyword with id {seed_keyword_id} does not exist'}) return super().update(instance, validated_data) def get_cluster_name(self, obj): """Get cluster name from Clusters model""" if obj.cluster_id: try: cluster = Clusters.objects.get(id=obj.cluster_id) return cluster.name except Clusters.DoesNotExist: return None return None def get_sector_name(self, obj): """Get sector name from Sector model""" if obj.sector_id: try: from igny8_core.auth.models import Sector sector = Sector.objects.get(id=obj.sector_id) return sector.name except Sector.DoesNotExist: return None return None class ClusterSerializer(serializers.ModelSerializer): """Serializer for Clusters model""" sector_name = serializers.SerializerMethodField() site_id = serializers.IntegerField(write_only=True, required=False) sector_id = serializers.IntegerField(write_only=True, required=False) class Meta: model = Clusters fields = [ 'id', 'name', 'description', 'keywords_count', 'volume', 'mapped_pages', 'status', 'sector_name', 'created_at', 'updated_at', 'site_id', 'sector_id', 'account_id', ] read_only_fields = ['id', 'created_at', 'updated_at', 'account_id', 'keywords_count', 'volume', 'mapped_pages'] def get_sector_name(self, obj): """Get sector name from Sector model""" if obj.sector_id: try: from igny8_core.auth.models import Sector sector = Sector.objects.get(id=obj.sector_id) return sector.name except Sector.DoesNotExist: return None return None def validate_name(self, value): """Ensure cluster name is unique within account""" # Uniqueness is handled at model level, but we can add additional validation here return value class ContentIdeasSerializer(serializers.ModelSerializer): """Serializer for ContentIdeas model""" keyword_cluster_name = serializers.SerializerMethodField() sector_name = serializers.SerializerMethodField() site_id = serializers.IntegerField(write_only=True, required=False) sector_id = serializers.IntegerField(write_only=True, required=False) class Meta: model = ContentIdeas fields = [ 'id', 'idea_title', 'description', 'content_structure', 'content_type', 'target_keywords', 'keyword_cluster_id', 'keyword_cluster_name', 'sector_name', 'status', 'estimated_word_count', 'created_at', 'updated_at', 'site_id', 'sector_id', 'account_id', ] read_only_fields = ['id', 'created_at', 'updated_at', 'account_id'] def get_keyword_cluster_name(self, obj): """Get cluster name from Clusters model""" if obj.keyword_cluster_id: try: cluster = Clusters.objects.get(id=obj.keyword_cluster_id) return cluster.name except Clusters.DoesNotExist: return None return None def get_sector_name(self, obj): """Get sector name from Sector model""" if obj.sector_id: try: from igny8_core.auth.models import Sector sector = Sector.objects.get(id=obj.sector_id) return sector.name except Sector.DoesNotExist: return None return None