from rest_framework import serializers from .models import OperatorAccount, PlatformAccount, Video import uuid from django.db.models import Q class OperatorAccountSerializer(serializers.ModelSerializer): id = serializers.IntegerField(read_only=True) # ID是自动递增的整数字段 class Meta: model = OperatorAccount fields = ['id', 'uuid', 'username', 'password', 'real_name', 'email', 'phone', 'position', 'department', 'is_active', 'created_at', 'updated_at'] read_only_fields = ['created_at', 'updated_at', 'uuid'] extra_kwargs = { 'password': {'write_only': True} } class PlatformAccountSerializer(serializers.ModelSerializer): operator_name = serializers.CharField(source='operator.real_name', read_only=True) platforms = serializers.SerializerMethodField() class Meta: model = PlatformAccount fields = ['id', 'operator', 'operator_name', 'name', 'platform_name', 'account_name', 'account_id', 'status', 'followers_count', 'account_url', 'description', 'tags', 'profile_image', 'last_posting', 'created_at', 'updated_at', 'last_login', 'platforms'] read_only_fields = ['id', 'created_at', 'updated_at'] def get_platforms(self, obj): # 不会在查询时调用,但需要实现该方法,默认返回空数组 return [] def to_internal_value(self, data): # 处理operator字段,可能是字符串格式的ID if 'operator' in data and isinstance(data['operator'], str): try: # 尝试获取对应的运营账号对象 operator = OperatorAccount.objects.get(id=data['operator']) data['operator'] = operator.id # 确保使用正确的ID格式 except OperatorAccount.DoesNotExist: # 如果找不到对应的运营账号,保持原值,让验证器捕获此错误 pass except Exception as e: # 其他类型的错误,如ID格式不正确等 pass # 处理platforms字段,从数组中提取出第一个元素的信息 if 'platforms' in data and isinstance(data['platforms'], list) and len(data['platforms']) > 0: data = data.copy() platform_data = data['platforms'][0] # 将platforms中的字段移到顶层 if 'platform_name' in platform_data: data['platform_name'] = platform_data['platform_name'] if 'account_url' in platform_data: data['account_url'] = platform_data['account_url'] if 'account_id' in platform_data: data['account_id'] = platform_data['account_id'] if 'account_name' in platform_data: data['account_name'] = platform_data['account_name'] # 删除platforms字段,避免验证错误 del data['platforms'] # 处理tags字段,将列表转换为逗号分隔的字符串 if 'tags' in data and isinstance(data['tags'], list): data = data.copy() if not isinstance(data, dict) else data data['tags'] = ','.join(data['tags']) return super().to_internal_value(data) def to_representation(self, instance): """将tags字符串转换为数组""" representation = super().to_representation(instance) if representation.get('tags'): representation['tags'] = representation['tags'].split(',') return representation class PlatformDetailSerializer(serializers.Serializer): """平台详情序列化器,用于多平台账号创建""" platform_name = serializers.ChoiceField(choices=PlatformAccount.PLATFORM_CHOICES) platform_url = serializers.URLField() class MultiPlatformAccountSerializer(serializers.Serializer): """多平台账号创建序列化器""" operator = serializers.PrimaryKeyRelatedField(queryset=OperatorAccount.objects.all()) name = serializers.CharField(max_length=100, required=False, allow_blank=True) account_name = serializers.CharField(max_length=100) account_id = serializers.CharField(max_length=100) status = serializers.ChoiceField(choices=PlatformAccount.STATUS_CHOICES, default='active') followers_count = serializers.IntegerField(default=0) description = serializers.CharField(required=False, allow_blank=True, allow_null=True) # 使用CharField而不是ListField,我们会在to_internal_value和to_representation中手动处理转换 tags = serializers.CharField(required=False, allow_blank=True, allow_null=True, max_length=255) profile_image = serializers.URLField(required=False, allow_blank=True, allow_null=True) last_posting = serializers.DateTimeField(required=False, allow_null=True) platforms = PlatformDetailSerializer(many=True) def to_internal_value(self, data): # 处理tags字段,将列表转换为逗号分隔的字符串 if 'tags' in data and isinstance(data['tags'], list): data = data.copy() data['tags'] = ','.join(data['tags']) # 处理operator字段,可能是字符串类型的ID if 'operator' in data and isinstance(data['operator'], str): try: # 尝试通过ID查找运营账号 operator_id = data['operator'] try: # 先尝试通过整数ID查找 operator_id_int = int(operator_id) operator = OperatorAccount.objects.get(id=operator_id_int) data['operator'] = operator.id except (ValueError, OperatorAccount.DoesNotExist): # 如果无法转换为整数或找不到对应账号,尝试通过用户名或真实姓名查找 operator = OperatorAccount.objects.filter( Q(username=operator_id) | Q(real_name=operator_id) ).first() if operator: data['operator'] = operator.id except Exception as e: pass return super().to_internal_value(data) def to_representation(self, instance): """将tags字符串转换为数组""" representation = super().to_representation(instance) if representation.get('tags') and isinstance(representation['tags'], str): representation['tags'] = representation['tags'].split(',') return representation class VideoSerializer(serializers.ModelSerializer): platform_account_name = serializers.CharField(source='platform_account.account_name', read_only=True) platform_name = serializers.CharField(source='platform_account.platform_name', read_only=True) class Meta: model = Video fields = ['id', 'platform_account', 'platform_account_name', 'platform_name', 'title', 'description', 'video_url', 'local_path', 'thumbnail_url', 'status', 'views_count', 'likes_count', 'comments_count', 'shares_count', 'tags', 'publish_time', 'video_id', 'created_at', 'updated_at'] read_only_fields = ['id', 'created_at', 'updated_at', 'views_count', 'likes_count', 'comments_count', 'shares_count'] def to_internal_value(self, data): # 处理tags字段,将列表转换为逗号分隔的字符串 if 'tags' in data and isinstance(data['tags'], list): data = data.copy() data['tags'] = ','.join(data['tags']) # 处理platform_account字段,可能是字符串格式的ID if 'platform_account' in data and isinstance(data['platform_account'], str): try: # 尝试获取对应的平台账号对象 platform_account = PlatformAccount.objects.get(id=data['platform_account']) data['platform_account'] = platform_account.id # 确保使用正确的ID格式 except PlatformAccount.DoesNotExist: # 如果找不到对应的平台账号,保持原值,让验证器捕获此错误 pass except Exception as e: # 其他类型的错误,如ID格式不正确等 pass return super().to_internal_value(data) def to_representation(self, instance): """将tags字符串转换为数组""" representation = super().to_representation(instance) if representation.get('tags'): representation['tags'] = representation['tags'].split(',') return representation