zoukankan      html  css  js  c++  java
  • Django-DRF认证,权限,限频,过滤,排序

    一、DRF自定义认证使用

    # 1 定义一个类,继承BaseAuthentication,重写authenticate方法
    class LoginAuth(BaseAuthentication):
        def authenticate(self, request):
            token = request.GET.get('token')
            res = models.UserToken.objects.filter(token=token).first()
            if res:
                return 元组  
            # 返回空或者元组,若返回元组则必须有两个值,第一个为self.request,第二个self.auth,self是request对象
            else:
                raise AuthenticationFailed('您没有登录')
    
                
    # 2 使用位置
    -局部使用:在视图类中配置
    authentication_classes = [MyAuthen.LoginAuth, ]  # 是个列表,可以写多个认证类,其中一个有返回值则不会执行后面
    -局部禁用:在视图类中配置空
    authentication_classes = []
    -全局使用:在settings中使用
    REST_FRAMEWORK = {
        "DEFAULT_AUTHENTICATION_CLASSES": ["app01.MyAuthen.LoginAuth", ]
    }
       
        
    # 3 注意:
    	1 认证类,认证通过可以返回一个元组,有两个值,第一个值会给,request.user,第二个值会个request.auth
        2 认证类可以配置多个,按照从前向后的顺序执行,如果前面有返回值,认证就不再继续往下走了
    

    二、DRF自定义权限使用

    权限的校验在认证之后,所以可以拿到前面return的request.user和request.auth

    # 1 使用写一个类继承BasePermission,重写has_permission
    
    # 假设某个视图中,超级用户为1,可以访问,除了超级用户以外,都不能访问
    class SuperPermission(BasePermission):
        # 若要打印中文错误信息可以在类中写message
        # message='错误信息提示'
        def has_permission(self, request, view):
            if request.user.user_type == '1':  # 此处使用了request.user需要认证里返回来,若不返回就拿不到
                return True
            else:
                return False
    
            
    # 2 使用位置
    -局部使用
    permission_classes = [MyAuthen.SuperPermission,]
    -局部禁用
    permission_classes = []
    -全局使用
    REST_FRAMEWORK = {
        "DEFAULT_PERMISSION_CLASSES": ["app01.MyAuthen.SuperPermission", ]
    }
    

    三、DRF自定义限率使用

    1.自己写一个,根据ip限制访问频率

    # 根据ip进行频率限制,每分钟只能访问3次,逻辑如下
    '''
    (1)取出访问者ip
    (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
    (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
    (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
    (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
    '''
    
    from rest_framework.throttling import BaseThrottle
    
    class MyThrottle(BaseThrottle):
        VISIT_RECORD = {}  # 存用户访问信息的大字典
        def __init__(self):
            self.history = None
        def allow_request(self,request,view):
            # (1)取出访问者ip
            ip = request.META.get('REMOTE_ADDR')
            import time
            ctime = time.time()
            # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问
            if ip not in self.VISIT_RECORD:
                self.VISIT_RECORD[ip] = [ctime, ]
                return True
            self.history = self.VISIT_RECORD.get(ip)
            # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
            while self.history and ctime - self.history[-1] > 60:
                self.history.pop()
            # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
            # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
            if len(self.history) < 3:
                self.history.insert(0, ctime)
                return True
            else:
                return False
    
        def wait(self):
            # 还剩多长时间能访问
            import time
            ctime = time.time()
            return 60 - (ctime - self.history[-1])
    

    2.自定义限制频率的步骤

    下面的SimpleRateThrottle已经帮我们实现了根据ip限制访问频率

    # 1 写一个类,继承SimpleRateThrottle
    class MySimpleThrottle(SimpleRateThrottle):
        scope = 'xxx'
        def get_cache_key(self, request, view):
            #什么都不写,就默认以ip限制
            return self.get_ident(request)
        
    -setting.py中配置
    REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_RATES' : {
            'xxx':'10/m'
            '''
            key跟scope对应,value是一个时间,表示每分钟十次,可以自己改,底层是用/分割,
            然后取右边第一个索引,所以写'10/mcbiaba'或'10/m'没区别
            '''
        }
    }
    
    
    # 2 使用位置
    -局部使用
    throttle_classes = [auth.MyThrottle,]
    -局部禁用
    throttle_classes = []
    -全局使用
    REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_CLASSES':['app01.auth.MyThrottle',],
    }
    
    

    3.其他内置限制频率类与使用

    # 内置频率类
    BaseThrottle:基类
    AnonRateThrottle:限制匿名用户的访问次数
    SimpleRateThrottle:一般用来继承他,然后我们自定义
    ScopedRateThrottle
    UserRateThrottle:限制登录用户访问次数
        
        
    # 其它内置频率类的使用
    AnonRateThrottle:限制匿名用户的访问次数,根据ip限制
    
    -局部使用
    throttle_classes = [throttling.AnonRateThrottle]
    -全局使用
    -setting.py中配置
    'DEFAULT_THROTTLE_RATES' : {
        'anon':'1/m'
    }
        
    
    UserRateThrottle:限制登录用户访问次数
    -限制登录用户访问次数UserRateThrottle(根据用户id限制)
    
    -局部使用
    throttle_classes = [throttling.UserRateThrottle]
    -全局使用
    -setting.py中配置
    'DEFAULT_THROTTLE_RATES' : {
        'user':'1/m'
    }
    

    四、DRF过滤与排序使用

    对于查询的结果,一般我们还需要经过一些过滤或者排序。

    DRF自己有内置的过滤功能,我们也可以使用第三方库,django-filter来过滤,也可以自己写自定义的过滤方法。

    # 1 内置筛选的使用
    -在视图类中配置
    filter_backends =[SearchFilter,]
    search_fields=('name',) # 表模型中的字段
    -查询的地址
    http://127.0.0.1:8000/students/?search=e  # 模糊查询
                    
    # 2 第三方扩展的过滤功能
    -pip3 install django-filter  :最新版本(2.4.0)要跟django2.2以上搭配
    -在视图类中配置
    filter_backends =[DjangoFilterBackend,]
    filter_fields=['name','age']
    -查询的时候
    http://127.0.0.1:8000/students/?name=lqz&age=18  # 精确查询
                    
                    
    # 3 自定义:
    # 写一个类MyFilter,继承BaseFilterBackend
    from rest_framework.filters import BaseFilterBackend
    
    # 重写filter_queryset方法,在该方法内部进行过滤(自己设置的过滤条件)并返回queryset
    class MyFilter(BaseFilterBackend):
        def filter_queryset(self, request, queryset, view):
            # 自己的过滤
            return queryset
    
    # 配置在视图类中
    	filter_backends = [MyFilter,]
    
  • 相关阅读:
    调试相关blogs收集
    union和union all
    V$SQLAREA
    Oracle Access和filter的区别
    Oracle 复合索引设计原理——前缀性和可选性
    经济学原理---8应用:税收的代价--- 读书笔记
    经济学原理---7 消费者.生产者与市场效率--- 读书笔记
    经济学原理---6 供给.需求与政府政策--- 读书笔记
    经济学原理---5 弹性及其应用 --- 读书笔记
    CURL---常见问题
  • 原文地址:https://www.cnblogs.com/chiyun/p/14066678.html
Copyright © 2011-2022 走看看