权限之model对象权限,查看所有对象时,过滤指定对象。操作单条对象时,判断有没有操作权限

先上结论:只有使用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下的listcreate方法

    第一种请求方式不涉及操作具体对象,仅查看所有对象和添加新的对象,走正常流程,没有对象的权限校验,只有对所有对象进行过滤,与权限无关

 

 

  第二种请求方式:get、put、delete,mixins类分别走mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin下的retrieveupdatedestroy方法

    第二种请求方式为单条对象操作,获取这单条对象走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

 

posted @ 2020-03-23 18:01  aikell  阅读(272)  评论(0)    收藏  举报