lty/qy_lty/userapp/serializers.py
pmc 61e8374e6a fix(affinity-P1): WR-002~WR-009 + IN-001~IN-006 综合改进收尾
WR-002 UserLevelRewardGrant.device on_delete CASCADE → SET_NULL,加 device_snapshot_id,
  unique 改为 partial(device 非空时唯一),与 AffinityLog.device SET_NULL 对齐
WR-003 AffinityLog 删除 3 个低价值索引(user/rule_key/source -created_at 复合)
WR-004 event_id 改为 null=True,partial unique 用 isnull=False;RunPython '' → NULL
WR-005 seed 加 companion_30min 默认规则
WR-006 description 显式 default='';DEFAULT_LEVELS 全部补 description
WR-007 seed_affinity 每条 spec 独立事务,部分失败可重跑
WR-008 ParadiseUser.favorability 字段保留 + UserInfoSerializer 移除暴露 + [DEPRECATED] 标记
WR-009(见 Commit B:AffinityLevel.clean + save full_clean 多层兜底)
IN-001 5 个弃用字段 help_text 加 [DEPRECATED — 计划于 P2 完成后删除]
IN-002 DEFAULT_RULES/LEVELS/SETTING 抽到 userapp/affinity/defaults.py
IN-003 AffinitySetting.daily_cap RenameField → global_daily_cap(区分 AffinityRule.daily_cap)
IN-004 AffinityLog.__str__ 用 pk or 'new' 兜底 None
IN-005(见 Commit A:is_active → is_bound 改名)
IN-006(见 Commit C:0006 print 前缀改为 [migration 0006_...])

迁移 0009 手工修正:daily_cap 改名用 RenameField(保留数据),不是 Remove+Add;
event_id '' → NULL 数据兜底;UserLevelRewardGrant on_delete + conditional unique 重建。

详见 docs/REVIEW-affinity-P1.md WR-* / IN-* 与 FIX-REPORT.md。
2026-05-13 10:18:47 +08:00

75 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from rest_framework import serializers
from allauth.account.adapter import get_adapter
from allauth.account.utils import setup_user_email
from dj_rest_auth.registration.serializers import RegisterSerializer
from dj_rest_auth.serializers import UserDetailsSerializer
from .models import ParadiseUser
class ParadiseUserSerializer(serializers.ModelSerializer):
"""
用于用户数据完整操作的序列化器
管理员使用
"""
class Meta:
model = ParadiseUser
fields = '__all__'
extra_kwargs = {
'password': {'write_only': True} # 确保密码字段永远不会被序列化返回
}
class UserInfoSerializer(serializers.ModelSerializer):
"""
用于展示用户信息的序列化器
用户自己查看
WR-008移除已弃用的 favorability 字段(已下沉到 UserDevice.favorability
前端需要显示好感度时,应通过设备级接口查询 UserDevice 列表。
"""
class Meta:
model = ParadiseUser
fields = ['id', 'username', 'email', 'phone_number', 'date_joined', 'last_login',
'gender', 'resident_city', 'birthday', 'zodiac_sign',
'mbti', 'interests', 'social_identity']
read_only_fields = ['id', 'date_joined', 'last_login']
class ProfileUpdateSerializer(serializers.ModelSerializer):
"""
用于用户更新个人资料的序列化器
"""
class Meta:
model = ParadiseUser
fields = ['gender', 'resident_city', 'birthday', 'zodiac_sign',
'mbti', 'interests', 'social_identity']
class CustomUserDetailsSerializer(UserDetailsSerializer):
"""
自定义 dj_rest_auth 用户详情序列化器
确保不返回敏感字段
"""
class Meta(UserDetailsSerializer.Meta):
model = ParadiseUser
exclude = ['password', 'user_permissions', 'groups']
read_only_fields = ['id', 'date_joined', 'last_login']
class CustomRegisterSerializer(RegisterSerializer):
email = serializers.EmailField(required=False)
phone_number = serializers.CharField(required=False, allow_blank=True, max_length=15)
def get_cleaned_data(self):
data = super().get_cleaned_data()
data['phone_number'] = self.validated_data.get('phone_number', '')
return data
def save(self, request):
user = super().save(request)
user.phone_number = self.cleaned_data.get('phone_number')
user.save()
return user