views.py 3.4 KB

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