REST-framework之频率控制

一 频率简介

为了控制用户对某个url请求的频率,比如,一分钟以内,只能访问三次

二 自定义频率类,自定义频率规则

自定义的逻辑

  1. """
  2. 1. 取出访问者ip
  3. 2. 判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
  4. 3. 循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
  5. 4. 判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
  6. 5. 当大于等于3,说明一分钟内访问超过三次,返回False验证失败
  7. """

代码实现:

  1. class MyThrottles():
  2. VISIT_RECORD = {}
  3. def __init__(self):
  4. self.history=None
  5. def allow_request(self,request, view):
  6. # 1. 取出访问者ip
  7. # print(request.META)
  8. ip=request.META.get('REMOTE_ADDR')
  9. import time
  10. ctime=time.time()
  11. # 2. 判断当前ip不在访问字典里,添加进去,
  12. # 并且直接返回True,表示第一次访问
  13. if ip not in self.VISIT_RECORD:
  14. self.VISIT_RECORD[ip]=[ctime,]
  15. return True
  16. self.history=self.VISIT_RECORD.get(ip)
  17. # 3. 循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个
  18. # 时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
  19. while self.history and ctime-self.history[-1]>60:
  20. self.history.pop()
  21. # 4. 判断,当列表小于3,说明一分钟以内访问不足三次,
  22. # 把当前时间插入到列表第一个位置,返回True,顺利通过
  23. # 5. 当大于等于3,说明一分钟内访问超过三次,返回False验证失败
  24. if len(self.history) < 3 :
  25. self.history.insert(0,ctime)
  26. return True
  27. else:
  28. return False
  29. def wait(self):
  30. import time
  31. ctime=time.time()
  32. return 60-(ctime-self.history[-1])

三 内置频率类及局部使用

写一个类,继承自SimpleRateThrottle,(根据ip限制)问:要根据用户现在怎么写

  1. from rest_framework.throttling import SimpleRateThrottle
  2. class VisitThrottle(SimpleRateThrottle):
  3. scope = 'luffy'
  4. def get_cache_key(self, request, view):
  5. return self.get_ident(request)

在setting里配置:(一分钟访问三次)

  1. REST_FRAMEWORK = {
  2. 'DEFAULT_THROTTLE_RATES':{
  3. 'luffy':'3/m'
  4. }
  5. }

在视图类里使用

  1. throttle_classes = [MyThrottles,]

错误信息的中文提示:

  1. class Course(APIView):
  2. authentication_classes = [TokenAuth, ]
  3. permission_classes = [UserPermission, ]
  4. throttle_classes = [MyThrottles,]
  5. def get(self, request):
  6. return HttpResponse('get')
  7. def post(self, request):
  8. return HttpResponse('post')
  9. def throttled(self, request, wait):
  10. from rest_framework.exceptions import Throttled
  11. class MyThrottled(Throttled):
  12. default_detail = '傻逼啊'
  13. extra_detail_singular = '还有 {wait} second.'
  14. extra_detail_plural = '出了 {wait} seconds.'
  15. raise MyThrottled(wait)

内置频率限制类:

BaseThrottle是所有类的基类

方法:def get_ident(self, request)获取标识,其实就是获取ip,自定义的需要继承它

1.AnonRateThrottle:未登录用户ip限制,需要配合auth模块用

2.SimpleRateThrottle:重写此方法,可以实现频率现在,不需要咱们手写上面自定义的逻辑

3.UserRateThrottle:登录用户频率限制,这个得配合auth模块来用

4.ScopedRateThrottle:应用在局部视图上的(忽略)

四 内置频率类及全局使用

  1. REST_FRAMEWORK = {
  2. 'DEFAULT_THROTTLE_CLASSES':['app01.utils.VisitThrottle',],
  3. 'DEFAULT_THROTTLE_RATES':{
  4. 'luffy':'3/m'
  5. }
  6. }

五 源码分析

  1. def check_throttles(self, request):
  2. for throttle in self.get_throttles():
  3. if not throttle.allow_request(request, self):
  4. self.throttled(request, throttle.wait())
  5. def throttled(self, request, wait):
  6. #抛异常,可以自定义异常,实现错误信息的中文显示
  7. raise exceptions.Throttled(wait)
  1. class SimpleRateThrottle(BaseThrottle):
  2. # 咱自己写的放在了全局变量,他的在django的缓存中
  3. cache = default_cache
  4. # 获取当前时间,跟咱写的一样
  5. timer = time.time
  6. # 做了一个字符串格式化,
  7. cache_format = 'throttle_%(scope)s_%(ident)s'
  8. scope = None
  9. # 从配置文件中取DEFAULT_THROTTLE_RATES,所以咱配置文件中应该配置,否则报错
  10. THROTTLE_RATES = api_settings.DEFAULT_THROTTLE_RATES
  11. def __init__(self):
  12. if not getattr(self, 'rate', None):
  13. # 从配置文件中找出scope配置的名字对应的值,比如咱写的‘3/m’,他取出来
  14. self.rate = self.get_rate()
  15. # 解析'3/m',解析成 3 m
  16. self.num_requests, self.duration = self.parse_rate(self.rate)
  17. # 这个方法需要重写
  18. def get_cache_key(self, request, view):
  19. """
  20. Should return a unique cache-key which can be used for throttling.
  21. Must be overridden.
  22. May return `None` if the request should not be throttled.
  23. """
  24. raise NotImplementedError('.get_cache_key() must be overridden')
  25. def get_rate(self):
  26. if not getattr(self, 'scope', None):
  27. msg = ("You must set either `.scope` or `.rate` for '%s' throttle" % (self.__class__.__name__)
  28. raise ImproperlyConfigured(msg)
  29. try:
  30. # 获取在setting里配置的字典中的之,self.scope是 咱写的luffy
  31. return self.THROTTLE_RATES[self.scope]
  32. except KeyError:
  33. msg = "No default throttle rate set for '%s' scope" % self.scope
  34. raise ImproperlyConfigured(msg)
  35. # 解析 3/m这种传参
  36. def parse_rate(self, rate):
  37. """
  38. Given the request rate string, return a two tuple of:
  39. <allowed number of requests>, <period of time in seconds>
  40. """
  41. if rate is None:
  42. return (None, None)
  43. num, period = rate.split('/')
  44. num_requests = int(num)
  45. # 只取了第一位,也就是 3/mimmmmmmm也是代表一分钟
  46. duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]
  47. return (num_requests, duration)
  48. # 逻辑跟咱自定义的相同
  49. def allow_request(self, request, view):
  50. """
  51. Implement the check to see if the request should be throttled.
  52. On success calls `throttle_success`.
  53. On failure calls `throttle_failure`.
  54. """
  55. if self.rate is None:
  56. return True
  57. self.key = self.get_cache_key(request, view)
  58. if self.key is None:
  59. return True
  60. self.history = self.cache.get(self.key, [])
  61. self.now = self.timer()
  62. # Drop any requests from the history which have now passed the
  63. # throttle duration
  64. while self.history and self.history[-1] <= self.now - self.duration:
  65. self.history.pop()
  66. if len(self.history) >= self.num_requests:
  67. return self.throttle_failure()
  68. return self.throttle_success()
  69. # 成功返回true,并且插入到缓存中
  70. def throttle_success(self):
  71. """
  72. Inserts the current request's timestamp along with the key
  73. into the cache.
  74. """
  75. self.history.insert(0, self.now)
  76. self.cache.set(self.key, self.history, self.duration)
  77. return True
  78. # 失败返回false
  79. def throttle_failure(self):
  80. """
  81. Called when a request to the API has failed due to throttling.
  82. """
  83. return False
  84. def wait(self):
  85. """
  86. Returns the recommended next request time in seconds.
  87. """
  88. if self.history:
  89. remaining_duration = self.duration - (self.now - self.history[-1])
  90. else:
  91. remaining_duration = self.duration
  92. available_requests = self.num_requests - len(self.history) + 1
  93. if available_requests <= 0:
  94. return None
  95. return remaining_duration / float(available_requests)

REST-framework之频率组件的更多相关文章

  1. restful framework之频率组件

    一.频率简介 为了控制用户对某个url请求的频率,比如,一分钟以内,只能访问三次 二.自定义频率类.自定义频率规则 自定义的逻辑 #(1)取出访问者ip # (2)判断当前ip不在访问字典里,添加进去 ...

  2. DRF Django REST framework 之 频率,响应器与分页器组件(六)

    频率组件 频率组件类似于权限组件,它判断是否给予请求通过.频率指示临时状态,并用于控制客户端可以向API发出的请求的速率. 与权限一样,可以使用多个调节器.API可能会对未经身份验证的请求进行限制,而 ...

  3. 基于Django的Rest Framework框架的频率组件

    0|1一.频率组件的作用 在我们平常浏览网站的时候会发现,一个功能你点击很多次后,系统会让你休息会在点击,这其实就是频率控制,主要作用是限制你在一定时间内提交请求的次数,减少服务器的压力. modle ...

  4. 前后端分离djangorestframework——限流频率组件

    频率限制 什么是频率限制 目前我们开发的都是API接口,且是开房的API接口.传给前端来处理的,也就是说,只要有人拿到这个接口,任何人都可以通过这个API接口获取数据,那么像网络爬虫的,请求速度又快, ...

  5. Rest_Framework之认证、权限、频率组件源码剖析

    一:使用RestFramwork,定义一个视图 from rest_framework.viewsets import ModelViewSet class BookView(ModelViewSet ...

  6. DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

  7. rest-framework频率组件

    throttle(访问频率)组件 1.局部视图throttle from rest_framework.throttling import BaseThrottle VISIT_RECORD={} c ...

  8. python全栈开发day101-认证组件、权限组件、频率组件

    1.Mixins类分析 这两个函数都在GenericAPIView下,这就是为什么必须搭配继承GenericAPIView的原因. 这两个主要是get_object()较为复杂. 2.认证组件源码分析 ...

  9. Django的rest_framework的权限组件和频率组件源码分析

    前言: Django的rest_framework一共有三大组件,分别为认证组件:perform_authentication,权限组件:check_permissions,频率组件:check_th ...

  10. drf频率组件

    1.简介 控制访问频率的组件 2.使用 手写一个自定义频率组件 import time #频率限制 #自定义频率组件,return True则可以访问,return False则不能访问 class ...

随机推荐

  1. 【JZOJ6210】【20190612】wsm

    题目 定义两个非递减数列的笛卡尔和数列\(C = A \oplus B\) 为\((A_i+B_j)\)排序后的非递减数列 \(W\)组询问,问有多少对可能的数列,满足: \(|C|=s,|A| = ...

  2. uni app 零基础小白到项目实战-1

    uni-app是一个使用vue.js开发跨平台应用的前端框架. 开发者通过编写vue.js代码,uni-app将其编译到Ios,android,微信小程序等多个平台,保证其正确并达到优秀体验. Uni ...

  3. 在Matlab中画图输出

    在Matlab中画图后,可能会调整格式.输出存储时,格式会忽然消失. 可以修改右下边Export setup,将Font size设置成auto. 这样就保留了编辑效果.

  4. Python3菜鸟教程笔记

    多行语句 同一行显示多条语句 Print 输出

  5. GoCN每日新闻(2019-10-09)

    GoCN每日新闻(2019-10-09) GoCN每日新闻(2019-10-09) 1. 我们如何将服务延迟减少了98% https://blog.gojekengineering.com/the-n ...

  6. httpd.exe你的电脑中缺失msvcr110.dll怎么办(WIN2008服务器环境装WAMP2.5出现的问题)

    httpd.exe你的电脑中缺失msvcr110.dll怎么办 去微软官方下载相应的文件 1 打开上面说的网址 Download and install, if you not have it alr ...

  7. HTTP/1.0和HTTP/1.1 http2.0的区别,HTTP怎么处理长连接(阿里)

    HTTP1.0 HTTP 1.1主要区别 长连接 HTTP 1.0需要使用keep-alive参数来告知服务器端要建立一个长连接,而HTTP1.1默认支持长连接. HTTP是基于TCP/IP协议的,创 ...

  8. ubuntu之路——day15.1 只用python的numpy在底层检验参数初始化对模型的影响

    首先感谢这位博主整理的Andrew Ng的deeplearning.ai的相关作业:https://blog.csdn.net/u013733326/article/details/79827273 ...

  9. CgLib实现AOP

    一.CgLib实现动态代理的例子 1.创建Person类 package com.example.cglib; public class Person { public void study(){ S ...

  10. 修改 commit 历史

    修改 commit 历史 参考:修改 git 历史提交 commit 信息(重写历史)git 修改已提交的内容 git init echo t.md>.gitignore git add .gi ...