python-DRF_限流Throttling_自定义频率类_内置频率类使用_过滤排序功能

9 篇文章 1 订阅

DRF-Django rest framework

认证权限频率

1. 限流Throttling

  • 可以对接口访问的频次进行限制,以减轻服务器压力

  • 一般用于付费购买次数,投票等场景使用

1. 自定义频率类

1. 限制某个用户,某个ip的访问频次

2. 自定义频率类及使用
'''
自定义的限制逻辑
	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):
        # 根据ip进行频率限制,每分钟只能访问3次
        # 1. 取出访问者ip
        # print(request.META)
        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])
    
3. 使用
	1. 局部使用
       # 在视图类里使用
			throttle_classes = [MyThrottles,]
    2. 全局使用
        REST_FRAMEWORK = {
        	'DEFAULT_THROTTLE_CLASSES':['app01.utils.MyThrottles',],
  		}

2. 内置频率类使用

1. 使用
	1. 局部使用
    	throttle_classes = [auth.MyThrottle,]
    2. 全局使用
    	REST_FRAMEWORK = {
    		'DEFAULT_THROTTLE_CLASSES':['app01.auth.MyThrottle',],
		}
        
2. 内置频率类
    BaseThrottle:      基类
	AnonRateThrottle:  限制匿名用户的访问次数
    SimpleRateThrottle:咱么自定义扩写它
    ScopedRateThrottle:
    UserRateThrottle:  限制登录用户访问次数
    
3. 扩展内置频率类
	# 1. 写一个类,继承SimpleRateThrottle
    class MySimpleThrottle(SimpleRateThrottle):
        scope = 'xxx'
        def get_cache_key(self, request, view):
            #以ip限制
            return self.get_ident(request)
        
    # 2. setting.py中配置
    	REST_FRAMEWORK = {
            'DEFAULT_THROTTLE_RATES' : {
                'xxx':'10/m'  # key跟scope对应,value是一个时间
            }
        }
        
	# 3. 限制匿名用户每分钟访问3次
    	REST_FRAMEWORK = {
            'DEFAULT_THROTTLE_CLASSES': (
                'rest_framework.throttling.AnonRateThrottle',
            ),
            'DEFAULT_THROTTLE_RATES': {
                'anon': '3/m',
            }
        }
        '''使用 `second`, `minute`, `hour` 或`day`来指明周期  可以全局使用 局部使用''' 
        
    # 4. 限制登陆用户每分钟访问10次
    	REST_FRAMEWORK = {
            'DEFAULT_THROTTLE_CLASSES': (
                'rest_framework.throttling.UserRateThrottle'
            ),
            'DEFAULT_THROTTLE_RATES': {
                'user': '10/m'
            }
        }
        
4. 源码分析
	继承SimpleRateThrottle  ==> allow_request(跟上面自定义的频率类一样)
       
5. 其它内置频率类
	1. AnonRateThrottle
		限制未登录用户的频率(根据ip限制)
    	使用:
        	-局部使用,全局使用
            -setting.py中配置
               'DEFAULT_THROTTLE_RATES' : {
        			'anon':'1/m'
    			}
                    
	2. UserRateThrottle               
    	限制登录用户访问次数 使用User id来区分(根据用户id限制)
        使用:
            -局部使用,全局使用
            -setting.py中配置
                'DEFAULT_THROTTLE_RATES' : {
                    'user':'1/m'
                }
                    
	3. ScopedRateThrottle                
    	限制用户对于每个视图的访问频次,使用 ip 或 user id
        # 示例
        class ContactListView(APIView):
            throttle_scope = 'contacts'
            ...

        class ContactDetailView(APIView):
            throttle_scope = 'contacts'
            ...

        class UploadView(APIView):
            throttle_scope = 'uploads'
            ...
        REST_FRAMEWORK = {
            'DEFAULT_THROTTLE_CLASSES': (
                'rest_framework.throttling.ScopedRateThrottle',
            ),
            'DEFAULT_THROTTLE_RATES': {
                'contacts': '1000/day',
                'uploads': '20/day'
            }
        }

3. 实例

# 全局配置中设置访问频率
	'DEFAULT_THROTTLE_RATES': {
        'anon': '3/minute',
        'user': '10/minute'
	 }

# 视图类        
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView
from rest_framework.throttling import UserRateThrottle

class StudentAPIView(RetrieveAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    authentication_classes = [SessionAuthentication]
    permission_classes = [IsAuthenticated]
    throttle_classes = (UserRateThrottle,)        

2. 过滤排序

1. 内置-第三方过滤Filtering

1. 过滤
	筛选查询结果

2. 内置筛选的使用
	# 在视图类中配置
        filter_backends =[SearchFilter,]
        search_fields=('name',) # 表模型中的字段
    # 查询的时候
    	http://127.0.0.1:8000/students/?search=e
                
3. 第三方扩展的过滤功能
	1. 安装第三方过滤模块
        pip3 install django-filter  
    	# 注意: 最新版本(2.4.0)要跟django2.2以上搭配
    
    2. 在视图类中配置
        filter_backends =[DjangoFilterBackend,]
    	filter_fields=['name','age']
        
    3. 在配置文件中增加过滤后端的设置
    INSTALLED_APPS = [
        ...
        'django_filters',  # 需要注册应用,
    ]

    REST_FRAMEWORK = {
        ...
        'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
    }

    4. 在视图中添加filter_fields属性,指定可以过滤的字段
		class StudentListView(ListAPIView):
            queryset = Student.objects.all()
            serializer_class = StudentSerializer
            filter_fields = ('age', 'sex')

    5. 查询的时候
        http://127.0.0.1:8000/students/?name=lqz&age=18

2. 排序功能

对于列表数据,REST framework 提供了 OrderingFilter 过滤器来帮助我们快速指明数据按照指定字段进行排序

使用方法:

在类视图中设置filter_backends,使用 rest_framework.filters.OrderingFilter 过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。

前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。

# 1. 排序 
    # 在视图类中配置
    class StudentListView(ListAPIView):
        queryset = Student.objects.all()
        serializer_class = StudentModelSerializer
        filter_backends =[OrderingFilter,]
        ordering_fields=['id','age']
        '''
            127.0.0.1:8000/books/?ordering=-age
            -id 表示针对id字段进行倒序排序
            id  表示针对id字段进行升序排序
        '''
    # 查询的时候
        http://127.0.0.1:8000/students/?ordering=-age          
            
# 2. 过滤后再排序
	# 在视图类中配置
    from rest_framework.generics import ListAPIView
    from students.models import Student
    from .serializers import StudentModelSerializer
    from django_filters.rest_framework import DjangoFilterBackend
    
    class Student3ListView(ListAPIView):
        queryset = Student.objects.all()
        serializer_class = StudentModelSerializer
        # 因为局部配置会覆盖全局配置,所以需要重新把过滤组件核心类再次声明,否则过滤功能会失效
        filter_backends = [OrderingFilter,DjangoFilterBackend]
        ordering_fields = ('id', 'age')
        filter_fields=['name','age']
        
	# 查询的时候
		http://127.0.0.1:8000/students/?name=lqz&age=19&ordering=-age,-id
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I believe I can fly~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值