先上结论:只有使用mixins类是才会进行model对象校验,以及对所有对象进行过滤(默认不过滤)。使用APIview时,get、put等操作都是在自己的CBV中实现,所以具体实现看自身需求。
使用rest_framwork时,CBV视图继承mixins类:
class AuthorDetailView(mixins.DestroyModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, generics.GenericAPIView): queryset = models.Author.objects.all() serializer_class = serializers.AuthorSerializers def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs)
或者更简洁的viewsets.ModelViewSet类:
class BookView(viewsets.ModelViewSet): authentication_classes = [utils.Authentication, ] # 认证组件,一个列表,类别中放认证类 permission_classes = [utils.PermissionCheck, ] # 权限组件, 一个列表, 列表中放权限类 throttle_classes = [utils.VisitThrottle, ] # 频率组件 queryset = models.Book.objects.all() serializer_class = serializers.BookSerializers
当用户通过用户认证校验,走到权限校验,不同的请求方式在mixins类下,权限校验有不同的处理方式:
第一种请求方式:get、post,mixins类走mixins.ListModelMixin,mixins.CreateModelMixin下的list和create方法
第一种请求方式不涉及操作具体对象,仅查看所有对象和添加新的对象,走正常流程,没有对象的权限校验,只有对所有对象进行过滤,与权限无关
第二种请求方式:get、put、delete,mixins类分别走mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin下的retrieve、update、destroy方法
第二种请求方式为单条对象操作,获取这单条对象走retrieve方法,获取单条obj后,他会对这条obj进行校验,校验规则自己在权限类中实现
默认走GenericAPIView类下的get_object()方法,可以自己覆盖它。当走默认方法时:
实现:
class PermissionCheck(object): message = "没有权限" # 这里的request属于APIview重新构造的reuqest,经过认证后,认证组件返回一个request.user和request.auth, # 这两个的返回结果在自己的认证类中自定义返回的结果,所以这里能够直接调用 def has_permission(self, request, view): # 校验权限 print(request.user.role, type(request.user.role)) self.obj = request.user if request.user.role == 3: return True else: return False def has_object_permission(self, request, view, obj): # 走mixins类,必须校验model对象, 不需要校验可以注释源码 # <rest_framework.request.Request object at 0x0000022C98FEC408> <app01.views.BookView object at 0x0000022C98FBEF48> 永丰异闻录 # print(request, view, obj) if obj.title in ['永丰异闻录', '白夜行']: return False return True