TradingAgents/web/backend/apps/authentication/serializers.py

145 lines
5.3 KiB
Python

from rest_framework import serializers
from django.contrib.auth import authenticate
from django.contrib.auth.password_validation import validate_password
from .models import User, UserProfile, AnalysisSession
class UserRegistrationSerializer(serializers.ModelSerializer):
"""사용자 회원가입 시리얼라이저"""
password = serializers.CharField(write_only=True, validators=[validate_password])
password_confirm = serializers.CharField(write_only=True)
class Meta:
model = User
fields = ('email', 'username', 'password', 'password_confirm', 'first_name', 'last_name')
def validate(self, attrs):
if attrs['password'] != attrs['password_confirm']:
raise serializers.ValidationError("비밀번호가 일치하지 않습니다.")
return attrs
def create(self, validated_data):
validated_data.pop('password_confirm')
user = User.objects.create_user(**validated_data)
return user
class UserLoginSerializer(serializers.Serializer):
"""사용자 로그인 시리얼라이저"""
email = serializers.EmailField()
password = serializers.CharField(write_only=True)
def validate(self, attrs):
email = attrs.get('email')
password = attrs.get('password')
if email and password:
user = authenticate(username=email, password=password)
if not user:
raise serializers.ValidationError('올바르지 않은 이메일 또는 비밀번호입니다.')
if not user.is_active:
raise serializers.ValidationError('비활성화된 계정입니다.')
attrs['user'] = user
else:
raise serializers.ValidationError('이메일과 비밀번호를 모두 입력해주세요.')
return attrs
class UserProfileSerializer(serializers.ModelSerializer):
"""사용자 프로필 시리얼라이저"""
has_openai_api_key = serializers.SerializerMethodField()
openai_api_key = serializers.CharField(write_only=True, required=False, allow_blank=True)
class Meta:
model = UserProfile
fields = (
'default_ticker',
'preferred_research_depth',
'preferred_shallow_thinker',
'preferred_deep_thinker',
'has_openai_api_key',
'openai_api_key',
'created_at',
'updated_at'
)
read_only_fields = ('created_at', 'updated_at')
def get_has_openai_api_key(self, obj):
return obj.has_openai_api_key()
def update(self, instance, validated_data):
openai_api_key = validated_data.pop('openai_api_key', None)
# OpenAI API 키 업데이트
if openai_api_key is not None:
instance.set_openai_api_key(openai_api_key)
# 다른 필드 업데이트
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
class UserSerializer(serializers.ModelSerializer):
"""사용자 정보 시리얼라이저"""
profile = UserProfileSerializer(read_only=True)
class Meta:
model = User
fields = ('id', 'email', 'username', 'first_name', 'last_name', 'profile', 'date_joined')
read_only_fields = ('id', 'email', 'date_joined')
class AnalysisSessionSerializer(serializers.ModelSerializer):
"""분석 세션 시리얼라이저"""
user_email = serializers.CharField(source='user.email', read_only=True)
duration = serializers.SerializerMethodField()
class Meta:
model = AnalysisSession
fields = (
'id', 'user_email', 'ticker', 'analysis_date',
'analysts_selected', 'research_depth', 'shallow_thinker', 'deep_thinker',
'status', 'final_report', 'error_message',
'created_at', 'started_at', 'completed_at', 'duration'
)
read_only_fields = ('id', 'user_email', 'created_at', 'duration')
def get_duration(self, obj):
if obj.started_at and obj.completed_at:
duration = obj.completed_at - obj.started_at
return int(duration.total_seconds())
return None
class CreateAnalysisSessionSerializer(serializers.ModelSerializer):
"""분석 세션 생성 시리얼라이저"""
class Meta:
model = AnalysisSession
fields = (
'ticker', 'analysis_date',
'analysts_selected', 'research_depth',
'shallow_thinker', 'deep_thinker'
)
def validate_analysts_selected(self, value):
"""선택된 분석가들 검증"""
if not isinstance(value, list) or len(value) == 0:
raise serializers.ValidationError("최소 하나의 분석가를 선택해야 합니다.")
valid_analysts = ['market', 'social', 'news', 'fundamentals']
for analyst in value:
if analyst not in valid_analysts:
raise serializers.ValidationError(f"올바르지 않은 분석가: {analyst}")
return value
def validate_research_depth(self, value):
"""연구 깊이 검증"""
if value not in [1, 3, 5]:
raise serializers.ValidationError("연구 깊이는 1, 3, 5 중 하나여야 합니다.")
return value