一、RestFramework之频率组件源码部分
频率组件的源码部分和权限组件流程一模一样的,这里就不多说了,直接上源码的主要逻辑部分:
def check_throttles(self, request):"""Check if request should be throttled.Raises an appropriate exception if the request is throttled."""for throttle in self.get_throttles():if not throttle.allow_request(request, self):self.throttled(request, throttle.wait())
明确表示我们写的频率类需要一个allow_request()方法:
频率类(完成一分钟同一个ip只能访问三次):
import time from rest_framework.throttling import BaseThrottleclass MyThrottle(BaseThrottle):visited_record = {}def __init__(self):self.history = Nonedef allow_request(self, request, my_cbv):# 这个my_cbv是源码中传的我们的视图类,这里我们也要传进去# print(self.get_ident(request)) # 可以获取本次请求的ipip = request.META.get("REMOTE_ADDR")if ip not in self.visited_record:self.visited_record[ip] = []current_time = time.time()history = self.visited_record[ip]self.history = historywhile history and current_time - history[-1] > 60: # 把与当前访问时间相差大于60秒的时间都删掉 history.pop()if len(history) > 2: # 第三次访问,列表中只有2个值,也满足条件,大于2个值时不满足条件return Falsehistory.insert(0, current_time)return Truedef wait(self):"""用于返回还剩多少时间访问;本次访问时间:9:50:55[09:50:30, 09:50:20, 09:50:10] 剩余 60 - (9:50:55 - 09:50:10)秒才能访问:return:"""c_time = time.time()return 60 - (c_time - self.history[-1])
视图类:
class BookView(ModelViewSet):authentication_classes = [UserAuth] #认证类permission_classes = [UserPerm] #权限类throttle_classes = [MyThrottle] #频率类queryset = Book.objects.all()serializer_class = BookSerializer
效果如下:
可以在全局settings配置
REST_FRAMEWORK = {'DEFAULT_PARSER_CLASSES': ('rest_framework.parsers.JSONParser','rest_framework.parsers.FormParser','rest_framework.parsers.MultiPartParser'),'DEFAULT_AUTHENTICATION_CLASSES': 'app01.utils.auth_class.UserAuth',),'DEFAULT_PERMISSION_CLASSES': ('app01.utils.permission_class.VipPermission',),'DEFAULT_THROTTLE_CLASSES': ('app01.utils.throttle_class.MyThrottle',), }
二、使用restframework组件中的提供的访问限制
实现方式和我们上面的方式基本相同;
基于限制ip的类:SimpleRateThrottle
基于ip的访问限制:
频率类——局部:
from rest_framework.throttling import SimpleRateThrottleclass MyThrottle(SimpleRateThrottle):rate = '5/m'def get_cache_key(self, request, view): # 这个方法也是必须要有return self.get_ident(request)
在视图类中指定频率类
class BookView(ModelViewSet):throttle_classes = [app_throttles.RateThrottle]queryset = Book.objects.all()serializer_class = BookSerializer
duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}
频率类——全局:
from rest_framework.throttling import SimpleRateThrottleclass MyThrottle(SimpleRateThrottle):scope = "visit_rate" # 这个值决定了在配置时使用哪个变量描述限制的频率,必须在settings里面配置def get_cache_key(self, request, view): # 这个方法也是必须要有return self.get_ident(request)
这次只能在setttings中配置:
REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ('app01.utils.throttle_class.MyThrottle',),"DEFAULT_THROTTLE_RATES": {"visit_rate": "10/m", # 这个参数就是频率类中定义的那个参数scope, 其中第一个数字10表示10次,后面的m表示一分钟,还有s,一秒, h, 一小时, d, 一天 } }
duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}