第一步: 重写
1.前端在进入到更改用户信息的界面, 会向后端索取用户的各种信息, 但是前端并不知道用户当前的id是多少, 而且后端之前也没配置get请求的接口, 所以配置如下
重写get_object后, 无论前端发过来什么数据 例如 /users/999/ , 后端都可以返回给前端当前用户的信息
class UserViewset(CreateModelMixin, mixins.RetrieveModelMixin,viewsets.GenericViewSet): ... # 给retrieve用的, 目的是给前端返回当前登录用户信息 def get_object(self): return self.request.user ...
2. 既然前端要获取用户登录的信息, 那么肯定前端发过来的请求要携带登录的信息,要么是session,要么是JWT token, 所以后端应该设置
permission_classes = (permissions.IsAuthenticated,)
但这么配置会导致一个问题, 会使我们在创建用户的时候也被迫要求处于登录状态, 这不是自相矛盾吗? 所以我们要动态的配置permission_classes, 不同的请求方式用不同的permission_classes
办法就是重写 APIView中的 get_permissions 方法(该方法原本的目的是遍历permission_classes, 并一个个返回) 源码如下
这里, 我们重写它, 当然配套的你还得指定认证方式, 这里设置JWT和session两种
class UserViewset(...)
...
# 登录的方式,session是为了浏览器验证方便 authentication_classes = (JSONWebTokenAuthentication,authentication.SessionAuthentication) # 动态配置permission_classes, 如果是create就不需要登录, 否则就要求登录 def get_permissions(self): if self.action == "retrieve": # 只有viewSet才能使用action的属性 return [permissions.IsAuthenticated()] # 返回实例 elif self.action == "create": return [] return []
3. 使用文档测试一下接口
4. 很明显, 因为我们之前的设置, (下图), 所以只返回这两个字段, 如果要返回其它字段信息, 我们不得不重写一个serializer,
并且在viewSet里面动态使用serializer, 即重写GenericAPIView的get_serializer_class, 和重写get_permissions逻辑差不多
users.serializers.py
# 用户详情的序列化类 class UserDetailSerializer(serializers.ModelSerializer): """ 用户详情的序列化类 """ class Meta: model = User fields = ("name","gender","birthday","email","mobile")
views.py
# 动态配置serializer_class, 如果是create就用UserRegSerializer, 否则就用UserDetailSerializer def get_serializer_class(self): if self.action == "retrieve": # 只有viewSet才能使用action的属性 return UserDetailSerializer elif self.action == "create": return UserRegSerializer return UserDetailSerializer
使用文档去测试接口, 成功返回了想要的字段
--- 君子处其实,不处其华;治其内,不治其外 张居正 ----
原文:https://www.cnblogs.com/jiangzongyou/p/12120032.html