12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- from rest_framework import serializers
- from .models import CustomUser # 导入你的 CustomUser 模型
- from django.contrib.auth.password_validation import validate_password # Django 自带密码验证
- # from django.core.exceptions import ValidationError # 如果需要在 validate 方法中手动抛出
- class UserRegistrationSerializer(serializers.ModelSerializer):
- password = serializers.CharField(
- write_only=True,
- required=True,
- validators=[validate_password],
- style={'input_type': 'password'} # 在DRF的可浏览API中显示为密码输入框
- )
- password2 = serializers.CharField(
- write_only=True,
- required=True,
- label="确认密码", # 在DRF的可浏览API中的标签
- style={'input_type': 'password'}
- )
- # 如果avatar是注册时可选上传的,确保在Meta中处理
- avatar = serializers.ImageField(required=False, allow_null=True, max_length=None, use_url=True)
- class Meta:
- model = CustomUser
- # 列出注册时需要用户提供的字段
- # 确保这些字段与 CustomUser 模型中定义的一致,特别是 USERNAME_FIELD 和 REQUIRED_FIELDS
- fields = ('email', 'phone_number', 'nickname', 'password', 'password2', 'school', 'bio', 'avatar')
- extra_kwargs = {
- # password 和 password2 已经在上面定义了 write_only=True
- 'nickname': {'required': True}, # 根据你的 CustomUser.REQUIRED_FIELDS,nickname是必填
- 'school': {'required': False, 'allow_blank': True},
- 'bio': {'required': False, 'allow_blank': True},
- # 'avatar': {'required': False} # 已经在上面字段定义中处理
- }
- def validate(self, attrs):
- if attrs['password'] != attrs['password2']:
- raise serializers.ValidationError({"password2": "两次输入的密码不匹配。"}) # 将错误关联到password2字段
- return attrs
- def create(self, validated_data):
- validated_data.pop('password2') # 移除 password2,它不需要保存到模型
-
- # 使用 CustomUser 模型的 create_user 方法创建用户
- # 它会处理密码哈希
- # validated_data 现在包含了 'email', 'phone_number', 'password', 'nickname' 以及可选的 'school', 'bio', 'avatar'
- user = CustomUser.objects.create_user(**validated_data)
- return user
- class UserProfileSerializer(serializers.ModelSerializer):
- """
- 用于获取和更新用户个人资料的序列化器。
- """
- avatar_url = serializers.SerializerMethodField() # 用于获取完整的头像URL
- class Meta:
- model = CustomUser
- # 列出用户可以查看和修改的字段
- # 不应包含敏感信息如 password (除非是 write_only 用于修改密码的特殊场景)
- fields = (
- 'id', 'email', 'phone_number', 'nickname',
- 'avatar', 'avatar_url', 'bio', 'school',
- 'date_joined', 'last_login', 'is_active' # is_active 可以考虑是否允许用户自己修改
- )
- # 定义只读字段 (在更新时不能被修改,或者需要特殊流程)
- read_only_fields = ('id', 'email', 'phone_number', 'date_joined', 'last_login', 'avatar_url')
- # avatar 字段本身可以用于上传,所以不是read_only,但 avatar_url 是只读的。
- # email 和 phone_number 通常不应通过这个接口随意更改,如果允许更改,需要额外的验证流程(比如发送验证码)。
- def get_avatar_url(self, obj):
- request = self.context.get('request')
- if obj.avatar and hasattr(obj.avatar, 'url'):
- if request is not None:
- return request.build_absolute_uri(obj.avatar.url)
- return obj.avatar.url # Fallback if request is not available
- return None # 如果没有头像或无法获取URL
- # 如果允许通过这个Serializer更新头像,不需要特别做什么,DRF的ModelSerializer会自动处理ImageField
- # 确保在视图中传递 request 到 serializer context,以便生成完整的URL
|