在前端要写个人信息中心的个人资料修改的时候需要后端返回用户的个人信息。
需要UserViewset类继承RetrieveModelMixin类,获取用户详情
from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin
class UserViewset(CreateModelMixin, RetrieveModelMixin, viewsets.GenericViewSet):
我们之前写的UserViewset没有返回用户id,所以前端压根不知道要怎么凑用户详情的url
url通常是:users/id/ 但是不知道ID 凑不了
有两种方法,一种是返回id给前端,第二种是重写get_object()
def get_object(self):
return self.request.user
这样的话前端不用知道用户id是多少 反正都是在处理当前用户。
get_object函数在前端发起retrieve和del请求时会调用。
源代码
class GenericAPIView(views.APIView):
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
class UserViewset(CreateModelMixin, RetrieveModelMixin, viewsets.GenericViewSet):
def get_object(self):
"""
Returns the object the view is displaying.
You may want to override this if you need to provide non-standard
queryset lookups. Eg if objects are referenced using multiple
keyword arguments in the url conf.
"""
queryset = self.filter_queryset(self.get_queryset())
接下来有一个问题:
登录验证。因为用户要修改用户信息肯定是在已登录的状态下处理的。但是 咱们UserViewset又有用于用户注册,在用户注册的时候不可能做登陆验证嘛 对吧。
咋搞?
这是正常的登陆验证。不过这里不适用用户注册的情况
class UserViewset(CreateModelMixin, RetrieveModelMixin, viewsets.GenericViewSet):
permission_classes = (permissions.IsAuthenticated, )
所以重写get_permissions() 因为在做验证的时候 GenericViewSet是调用父类APIView中get_permissions函数来决定使用哪种验证机制 我们重写他就好
class UserViewset(CreateModelMixin, RetrieveModelMixin, viewsets.GenericViewSet):
def get_permissions(self):
# 如果是retrieve请求
# 这个action只有在ViewSet中存在
if self.action == 'retrieve':
return [permissions.IsAuthenticated()]
# 如果是create请求
elif self.action == 'create':
return []
return []
源码
class APIView(View):
class GenericAPIView(views.APIView):
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
class UserViewset(CreateModelMixin, RetrieveModelMixin, viewsets.GenericViewSet):
def get_permissions(self):
"""
Instantiates and returns the list of permissions that this view requires.
"""
return [permission() for permission in self.permission_classes]
然后加上登录验证模式
# ------------------------>用于接口测试
authentication_classes = (authentication.SessionAuthentication, JSONWebTokenAuthentication)
这时候就搞定了 注册和获取用户信息采用不同的权限验证方式了
可以通过文档登录测试下
测试的时候发现 获取的字段不对
这就需要我们用另一个serializer来序列化出新的字段列表
class UserDetailSerializer(serializers.ModelSerializer):
"""
用户详情序列化类
"""
class Meta:
model = User
fields = ('name', 'gender', 'birthday', 'email', 'mobile')
现在我们采用的是对象成员,这是不行的 这样只能返回用户名和手机号
serializer_class = UserRegSerializer
我们需要重写get_serializer_class函数
from .serializers import UserRegSerializer, UserDetailSerializer
def get_serializer_class(self):
if self.action == 'retrieve':
return UserDetailSerializer
elif self.action == 'create':
return UserRegSerializer
return UserDetailSerializer
get_serializer_class的源代码
class GenericAPIView(views.APIView):
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
class UserViewset(CreateModelMixin, RetrieveModelMixin, viewsets.GenericViewSet):
def get_serializer_class(self):
"""
Return the class to use for the serializer.
Defaults to using `self.serializer_class`.
You may want to override this if you need to provide different
serializations depending on the incoming request.
(Eg. admins get full serialization, others get basic serialization)
"""
assert self.serializer_class is not None, (
"'%s' should either include a `serializer_class` attribute, "
"or override the `get_serializer_class()` method."
% self.__class__.__name__
)
return self.serializer_class
效果
搞定 完结