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,]
    
  • 相关阅读:
    笨方法学python中执行argv提示ValueError: not enough values to unpack (expected 4, got 1)
    VMware workstation安装
    Redis bigkey分析
    MySQL drop table 影响及过程
    MySQL 大表硬连接删除
    ES elasticsearch 各种查询
    ES elasticsearch 各种聚合
    ES elasticsearch 聚合统计
    ES elasticsearch 实现 count单字段,分组取前多少位,以地理位置中心进行统计
    MySQL行溢出、varchar最多能存多少字符
  • 原文地址:https://www.cnblogs.com/chiyun/p/14066678.html
Copyright © 2011-2022 走看看