Django REST framework之节流组件实例以及源码流程分析

抛出问题

对访问的频率进行控制(当然只是在一定程度上限制,若客服端换IP,疯狂注册账号没治)

通过获取用户的IP,实现一分钟内,只能访问三次。实际生产中应该记录放在数据库,或者放在缓存,或者放在文件中等等,我把记录直接放在这里,占用内存不说,还有就是服务端从启系统的话,记录全丢失。

视图路由与认证权限相同。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from rest_framework.throttling import BaseThrottle
 5 from rest_framework.throttling import SimpleRateThrottle
 6 import time
 7 
 8 VIST_RECORD = {}
 9 
10 
11 class VisitThrottle(BaseThrottle):
12 
13     def __init__(self):
14         self.history = None
15 
16     def allow_request(self, request, view):
17 
18         """
19         一分钟访问三次最多
20         判断是否可以继续访问,频率是否达到最大
21         :param request:
22         :param view:
23         :return: True 可以继续访问 False表示访问频率太高要被限制
24         1.获取用户IP
25         """
26         remote_addr = request.META.get('REMOTE_ADDR')
27         ctime = time.time()
28         if remote_addr not in VIST_RECORD:
29             VIST_RECORD[remote_addr] = [ctime,]
30             return True
31         history = VIST_RECORD.get(remote_addr)
32         self.history = history
33         while history and history[-1] < ctime - 60:
34             history.pop()
35 
36         if len(history) < 3:
37             history.insert(0, ctime)
38             return True
39 
40     def wait(self):
41         """
42         还需要等多久才能被访问
43         :return:
44         """
45         ctime = time.time()
46         return 60 - (ctime - self.history[-1])

当然内置的页帮我们写了这些环节,直接获取过来用即可

 1 class VisitThrottle(SimpleRateThrottle):
 2     scope = "Baidu"
 3 
 4     def get_cache_key(self, request, view):
 5         return self.get_ident(request)
 6 
 7 
 8 class UserThrottle(SimpleRateThrottle):
 9     """
10     根据当前登录用户的访问次数限制
11     """
12     scope = "BaiduUser"
13 
14     def get_cache_key(self, request, view):
15         return request.user.username

全局配置:

 1 REST_FRAMEWORK = {
 2     # 认证
 3     'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.auth.Authticate', ],
 4     # 'DEFAULT_AUTHENTICATION_CLASSES': [],  # AnonymousUser None配置文件中有
 5     # 'UNAUTHENTICATED_USER': lambda: '匿名用户',
 6     # 'UNAUTHENTICATED_USER': None,
 7     # 'UNAUTHENTICATED_TOKEN': None,
 8     # 权限
 9     'DEFAULT_PERMISSION_CLASSES': ['api.utils.permission.Mypermission'],
10     # 节流 访问频率控制
11     "DEFAULT_THROTTLE_CLASSES": ['api.utils.throttle.VisitThrottle', ],
12     "DEFAULT_THROTTLE_RATES": {
13         "Baidu": '3/m',
14         "BaiduUser": '10/m',
15     }
16 
17 }

局部配置:

1 throttle_classes = [VisitThrottle, ]

总结:自己定义节流类,在类中实现allow_request(都是这样子若没写前面几个组件都是抛错,看基类),wait两方法,当然wait可以不用写,当然看需求吧!

源码流程分析

 APIView的dispatch---->封装request----->initial----->self.check_throttles(request)----->allow_request(request, self)(两种情况:True访问频率未达到最高次数,Flase访问频率已经达到最大的次数)

内置节流类

BaseThrottle allow_request主逻辑  get_ident获取IP wait超过次数需要多久恢复

SimpleRateThrottle 适用 跟我上面实现思路差不多 在settings中配置scope即可快捷

AnonRateThrottle 针对匿名用户的 配置scope = 'anon'

UserRateThrottle scope = 'user'

ScopedRateThrottle scope_attr = 'throttle_scope'



猜你喜欢

转载自www.cnblogs.com/Alexephor/p/11296521.html