operations_project/apps/operation/serializers.py

179 lines
8.6 KiB
Python
Raw Normal View History

2025-05-13 11:58:17 +08:00
from rest_framework import serializers
from .models import OperatorAccount, PlatformAccount, Video
import uuid
2025-05-20 15:57:10 +08:00
from django.db.models import Q
2025-05-13 11:58:17 +08:00
class OperatorAccountSerializer(serializers.ModelSerializer):
2025-05-20 15:57:10 +08:00
id = serializers.IntegerField(read_only=True) # ID是自动递增的整数字段
2025-05-13 11:58:17 +08:00
class Meta:
model = OperatorAccount
2025-05-20 15:57:10 +08:00
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']
2025-05-13 11:58:17 +08:00
extra_kwargs = {
'password': {'write_only': True}
}
class PlatformAccountSerializer(serializers.ModelSerializer):
operator_name = serializers.CharField(source='operator.real_name', read_only=True)
2025-05-20 15:57:10 +08:00
platforms = serializers.SerializerMethodField()
2025-05-13 11:58:17 +08:00
class Meta:
model = PlatformAccount
2025-05-20 15:57:10 +08:00
fields = ['id', 'operator', 'operator_name', 'name', 'platform_name', 'account_name', 'account_id',
2025-05-13 11:58:17 +08:00
'status', 'followers_count', 'account_url', 'description',
'tags', 'profile_image', 'last_posting',
2025-05-20 15:57:10 +08:00
'created_at', 'updated_at', 'last_login', 'platforms']
2025-05-13 11:58:17 +08:00
read_only_fields = ['id', 'created_at', 'updated_at']
2025-05-20 15:57:10 +08:00
def get_platforms(self, obj):
# 不会在查询时调用,但需要实现该方法,默认返回空数组
return []
2025-05-13 11:58:17 +08:00
def to_internal_value(self, data):
2025-05-20 15:57:10 +08:00
# 处理operator字段可能是字符串格式的ID
2025-05-13 11:58:17 +08:00
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
2025-05-20 15:57:10 +08:00
# 处理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'])
2025-05-13 11:58:17 +08:00
return super().to_internal_value(data)
2025-05-20 15:57:10 +08:00
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
2025-05-13 11:58:17 +08:00
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',
2025-05-20 15:57:10 +08:00
'publish_time', 'video_id', 'created_at', 'updated_at']
2025-05-13 11:58:17 +08:00
read_only_fields = ['id', 'created_at', 'updated_at', 'views_count', 'likes_count',
'comments_count', 'shares_count']
def to_internal_value(self, data):
2025-05-20 15:57:10 +08:00
# 处理tags字段将列表转换为逗号分隔的字符串
if 'tags' in data and isinstance(data['tags'], list):
data = data.copy()
data['tags'] = ','.join(data['tags'])
# 处理platform_account字段可能是字符串格式的ID
2025-05-13 11:58:17 +08:00
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)
2025-05-20 15:57:10 +08:00
def to_representation(self, instance):
"""将tags字符串转换为数组"""
representation = super().to_representation(instance)
if representation.get('tags'):
representation['tags'] = representation['tags'].split(',')
return representation