zoukankan      html  css  js  c++  java
  • 权限 频率 过滤 异常处理,封装对象

    今日内容

    1 权限

    1.1 权限源码分析

    # APIView---->dispatch---->initial--->self.check_permissions(request)(APIView的对象方法)
        def check_permissions(self, request):
            # 遍历权限对象列表得到一个个权限对象(权限器),进行权限认证
            for permission in self.get_permissions():
                # 权限类一定有一个has_permission权限方法,用来做权限认证的
                # 参数:权限对象self、请求对象request、视图类对象
                # 返回值:有权限返回True,无权限返回False
                if not permission.has_permission(request, self):
                    self.permission_denied(
                        request, message=getattr(permission, 'message', None)
                    )
    

    1.2 权限的使用

    # 写一个类,继承BasePermission,重写has_permission,如果权限通过,就返回True,不通过就返回False
    from rest_framework.permissions import BasePermission
    
    class UserPermission(BasePermission):
        def  has_permission(self, request, view):
            # 不是超级用户,不能访问
            # 由于认证已经过了,request内就有user对象了,当前登录用户
            user=request.user  # 当前登录用户
            # 如果该字段用了choice,通过get_字段名_display()就能取出choice后面的中文
            print(user.get_user_type_display())
            if user.user_type==1:
                return True
            else:
                return False
            
    # 局部使用
    class TestView(APIView):
        permission_classes = [app_auth.UserPermission]
    # 全局使用
    REST_FRAMEWORK={
        "DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",],
        'DEFAULT_PERMISSION_CLASSES': [
            'app01.app_auth.UserPermission',
        ],
    }
    # 局部禁用
    class TestView(APIView):
        permission_classes = []
    

    1.3 内置权限(了解)

    # 演示一下内置权限的使用:IsAdminUser,控制是否对网站后台有权限的人
    # 1 创建超级管理员
    # 2 写一个测试视图类
    from rest_framework.permissions import IsAdminUser
    from rest_framework.authentication import SessionAuthentication
    class TestView3(APIView):
        authentication_classes=[SessionAuthentication,]
        permission_classes = [IsAdminUser]
        def get(self,request,*args,**kwargs):
            return Response('这是22222222测试数据,超级管理员可以看')
    # 3 超级用户登录到admin,再访问test3就有权限
    # 4 正常的话,普通管理员,没有权限看(判断的是is_staff字段)
    

    2 频率

    2.1 内置的频率限制(限制未登录用户)

    # 全局使用  限制未登录用户1分钟访问5次
    REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_CLASSES': (
            'rest_framework.throttling.AnonRateThrottle',
        ),
        'DEFAULT_THROTTLE_RATES': {
            'anon': '3/m',
        }
    }
    ##############views.py
    from rest_framework.permissions import IsAdminUser
    from rest_framework.authentication import SessionAuthentication,BasicAuthentication
    class TestView4(APIView):
        authentication_classes=[]
        permission_classes = []
        def get(self,request,*args,**kwargs):
            return Response('我是未登录用户')
    
    # 局部使用
    from rest_framework.permissions import IsAdminUser
    from rest_framework.authentication import SessionAuthentication,BasicAuthentication
    from rest_framework.throttling import AnonRateThrottle
    class TestView5(APIView):
        authentication_classes=[]
        permission_classes = []
        throttle_classes = [AnonRateThrottle]
        def get(self,request,*args,**kwargs):
            return Response('我是未登录用户,TestView5')
    

    2.2 内置频率限制之,限制登录用户的访问频次

    # 需求:未登录用户1分钟访问5次,登录用户一分钟访问10次
    全局:在setting中
      'DEFAULT_THROTTLE_CLASSES': (
            'rest_framework.throttling.AnonRateThrottle',
            'rest_framework.throttling.UserRateThrottle'
        ),
        'DEFAULT_THROTTLE_RATES': {
            'user': '10/m',
            'anon': '5/m',
        }
            
     局部配置:
    	在视图类中配一个就行
    

    3 过滤

    #1 安装:pip3 install django-filter
    #2 注册,在app中注册
    #3 全局配,或者局部配
     'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
    #4 视图类
    class BookView(ListAPIView):
        queryset = Book.objects.all()
        serializer_class = BookSerializer
        filter_fields = ('name',)  #配置可以按照哪个字段来过滤
    

    4 排序

    # 局部使用和全局使用
    # 局部使用
    from rest_framework.generics import ListAPIView
    from rest_framework.filters import OrderingFilter
    from app01.models import Book
    from app01.ser import BookSerializer
    class Book2View(ListAPIView):
        queryset = Book.objects.all()
        serializer_class = BookSerializer
        filter_backends = [OrderingFilter]
        ordering_fields = ('id', 'price')
        
    # urls.py
    path('books2/', views.Book2View.as_view()),
    ]
    
    # 使用:
    http://127.0.0.1:8000/books2/?ordering=-price
    http://127.0.0.1:8000/books2/?ordering=price
    http://127.0.0.1:8000/books2/?ordering=-id
    

    5 异常处理

    #统一接口返回
    
    # 自定义异常方法,替换掉全局
    # 写一个方法
    # 自定义异常处理的方法
    from rest_framework.views import exception_handler
    from rest_framework.response import Response
    from rest_framework import status
    def my_exception_handler(exc, context):
        response=exception_handler(exc, context)
        # 两种情况,一个是None,drf没有处理
        #response对象,django处理了,但是处理的不符合咱们的要求
        # print(type(exc))
    
        if not response:
            if isinstance(exc, ZeroDivisionError):
                return Response(data={'status': 777, 'msg': "除以0的错误" + str(exc)}, status=status.HTTP_400_BAD_REQUEST)
            return Response(data={'status':999,'msg':str(exc)},status=status.HTTP_400_BAD_REQUEST)
        else:
            # return response
            return Response(data={'status':888,'msg':response.data.get('detail')},status=status.HTTP_400_BAD_REQUEST)
        
    # 全局配置setting.py
    'EXCEPTION_HANDLER': 'app01.app_auth.my_exception_handler',
    
    

    6 封装Response对象(重要)

    # 以后都用自己封装的
    class APIResponse(Response):
        def __init__(self,code=100,msg='成功',data=None,status=None,headers=None,**kwargs):
            dic = {'code': code, 'msg': msg}
            if  data:
                dic = {'code': code, 'msg': msg,'data':data}
            dic.update(kwargs)
            super().__init__(data=dic, status=status,headers=headers)
    # 使用
    return APIResponse(data={"name":'lqz'},token='dsafsdfa',aa='dsafdsafasfdee')
    return APIResponse(data={"name":'lqz'})
    return APIResponse(code='101',msg='错误',data={"name":'lqz'},token='dsafsdfa',aa='dsafdsafasfdee',header={})
    

    补充

    1 变量后直接加逗号

    a=(3,)
    a=3,  # a是元组
    print(type(a))
    
  • 相关阅读:
    javaweb消息中间件——rabbitmq入门
    virtual box 桥接模式(bridge adapter)下无法获取ip(determine ip failed)的解决方法
    Apache Kylin本地启动
    git操作
    Java学习总结
    Java中同步的几种实现方式
    hibernate exception nested transactions not supported 解决方法
    vue 中解决移动端使用 js sdk 在ios 上一直报invalid signature 的问题解决
    cookie 的使用
    vue 专门为了解决修改微信标题而生的项目
  • 原文地址:https://www.cnblogs.com/chenyoupan/p/13279292.html
Copyright © 2011-2022 走看看