12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- from rest_framework import generics, status, permissions
- from rest_framework.response import Response
- from rest_framework_simplejwt.tokens import RefreshToken # 用于登录时或注册后手动生成token
- # 从当前应用的 models.py 和 serializers.py 导入
- from .models import CustomUser
- from .serializers import UserRegistrationSerializer, UserProfileSerializer
- class UserRegistrationView(generics.CreateAPIView):
- """
- 用户注册视图。
- 允许任何人 (未认证用户) 访问此端点进行注册。
- """
- queryset = CustomUser.objects.all() # CreateAPIView 需要 queryset,即使我们不直接用它来过滤
- serializer_class = UserRegistrationSerializer
- permission_classes = [permissions.AllowAny] # 明确允许任何人访问此视图
- def create(self, request, *args, **kwargs):
- serializer = self.get_serializer(data=request.data)
- serializer.is_valid(raise_exception=True) # 如果数据无效,DRF会自动返回400错误和详细信息
- user = serializer.save() # 调用 serializer 的 create 方法,创建用户
- # 注册成功后,为用户生成JWT令牌 (实现注册即登录)
- refresh = RefreshToken.for_user(user)
- # 构建响应数据
- # 我们使用 UserProfileSerializer 来序列化新创建的 user 对象,以便返回更完整的用户信息
- # 需要传递 request 到 context 以便 UserProfileSerializer 中的 get_avatar_url 能构建完整URL
- user_data = UserProfileSerializer(user, context={'request': request}).data
-
- response_data = {
- 'refresh': str(refresh),
- 'access': str(refresh.access_token),
- 'user': user_data
- }
- return Response(response_data, status=status.HTTP_201_CREATED)
- class UserProfileView(generics.RetrieveUpdateAPIView):
- """
- 获取和更新当前已认证用户的个人资料视图。
- 只允许已认证的用户访问他们自己的个人资料。
- """
- queryset = CustomUser.objects.all() # RetrieveUpdateAPIView 也需要 queryset
- serializer_class = UserProfileSerializer
- permission_classes = [permissions.IsAuthenticated] # 明确只有认证用户才能访问
- def get_object(self):
- # 此方法返回视图将要操作的对象实例
- # 在这里,我们返回当前发出请求的认证用户
- return self.request.user
- # 当收到 PUT 或 PATCH 请求时,DRF的 RetrieveUpdateAPIView 会自动调用
- # serializer_class 的 update() 或 partial_update() 方法。
- # 我们在 UserProfileSerializer 中没有定义 update 方法,所以它会使用
- # ModelSerializer 的默认 update 行为,这对于 ImageField (如 avatar) 通常是有效的。
- # 如果需要更复杂的更新逻辑(例如,修改密码、验证邮箱/手机更改),则需要重写 update 方法。
- # 为了让 UserProfileSerializer 中的 get_avatar_url 能正确工作,
- # 我们需要确保 serializer 在实例化时能获取到 request 对象。
- # RetrieveUpdateAPIView 会自动将 request 传递给 serializer context。
- # def get_serializer_context(self):
- # context = super().get_serializer_context()
- # context.update({"request": self.request})
- # return context
- # 上面的 get_serializer_context 是DRF 3.9版本之后默认会做的,所以通常不需要显式重写。
- # 但如果头像URL不正确,可以尝试取消注释上面这段代码。
|