学习完rest_framework的权限,我们继续看“节流”功能是如何完成的。
一、 和认证、权限一样,从dispatch到initial方法,在initial的最后就是运行“节流”校验的函数(check_throttles)了。
def initial(self, request, *args, **kwargs):
self.format_kwarg = self.get_format_suffix(**kwargs)
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
# 认证
self.perform_authentication(request)
# 权限
self.check_permissions(request)
# 节流
self.check_throttles(request)
二、 check_throttles的过程和权限验证的过程是相似的,遍历self.get_throttles()返回的包含节流类的列表,然后执行每一个实例化后的节流类的allow_request方法。
如果节流失败,则返回True,如果全部节流失败,则节流验证通过; 如果节流成功,会执行节流类的wait方法(返回数字类型结果)并将返回结果放进throttle_durations中,等遍历完毕后,对throttle_durations进行空值排除,寻取最大值,得到duration然后运行self.throttled(request, duration)。
def check_throttles(self, request):
throttle_durations = []
for throttle in self.get_throttles(): # 遍历self.get_throttles()返回的结果
if not throttle.allow_request(request, self):
throttle_durations.append(throttle.wait())
if throttle_durations:
durations = [
duration for duration in throttle_durations
if duration is not None
]
duration = max(durations, default=None)
self.throttled(request, duration)
- self.get_throttles()的功能就是将self.throttle_classes中的每一个节流类实例化并放进列表中,返回给check_throttles方法。
def get_throttles(self):
return [throttle() for throttle in self.throttle_classes]
三、 throttled方法其实就是抛出了rest_framework.exceptions.Throttled异常,返回数据给前端,告知访问被节流和禁止访问的剩余时间
def throttled(self, request, wait):
raise exceptions.Throttled(wait)
四、 节流类在视图类的设置(局部)
与认证和权限一样,通过在视图类中添加throttle_classes属性可以为视图类添加节流的功能:
from rest_framework.permissions import AllowAny
from rest_framework.authentication import BaseAuthentication
from rest_framework.throttling import SimpleRateThrottle
class MyView(APIView):
authentication_classes = [BaseAuthentication,] # 认证类
permission_classes = [AllowAny,] # 权限类
throttle_classes = [SimpleRateThrottle,] # 节流类
def get(self, request, *args, **kwargs):
…………
rest_framework内置了五种节流类:BaseThrottle、SimpleRateThrottle、AnonRateThrottle、UserRateThrottle、ScopedRateThrottle。
五、 节流类的全局设置
在项目的settings.py中的REST_FRAMEWORK配置项中添加DEFAULT_THROTTLE_CLASSES,可以为项目设置全局的节流功能。
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["rest_framework.authentication.BaseAuthentication",], # 认证类
"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.AllowAny"], # 权限类
"DEFAULT_THROTTLE_CLASSES": ["rest_framework.permissions.SimpleRateThrottle"] # 节流类
}
六、 自定义节流类
有时候我们需要开发自己的节流功能,所以要自定义一些节流类。节流类必须包含两个方法:allow_request、wait,前者用于添加节流方法并返回True或False,后者用于提醒用户剩余的禁止访问时间。
class MyThrottle(object):
def allow_request(self, request, view):
return True
def wait(self):
return None