一 前言
經(jīng)過權(quán)限判斷之后就是進(jìn)行頻率的判斷了,而頻率的判斷和權(quán)限又不一樣,認(rèn)證、權(quán)限和頻率的執(zhí)行流程都差不多,使用配置里面的相關(guān)類來進(jìn)行判斷。而不和認(rèn)證和權(quán)限一樣,頻率的配置沒有,查看 APIView 的類屬性如下:


二 頻率組件執(zhí)行流程
雖然 restframework 原生滅有配置頻率,但是提供了幾個(gè)進(jìn)行頻率判斷的類,如下:

其中 SimpleRateThrottle 類是根據(jù)訪問者 ip 來進(jìn)行頻率限制的一個(gè)類,來看看這個(gè)類的執(zhí)行流程。
1. init方法

2. get_rate

3. 執(zhí)行 allow_request方法

4. get_cache_key

5. 時(shí)間差判斷

6. throttle_success

認(rèn)證失敗的話執(zhí)行 throttle_failure ,其實(shí)就是返回 False 。
7. wait

三 自定義頻率組件
1. 自定義頻率類
頻率類需要繼承自帶的頻率類
# from rest_framework.throttling import BaseThrottleclass BookThrottle(BaseThrottle):  VISIT_RECORD = {}  def __init__(self):    self.history = None  def allow_request(self, request, view):    print(request.META)    REMOTE_ADDR = request.META.get('REMOTE_ADDR')    import time    ctime = time.time()    if REMOTE_ADDR not in self.VISIT_RECORD:      self.VISIT_RECORD[REMOTE_ADDR] = [ctime,]      return True    self.history = self.VISIT_RECORD.get(REMOTE_ADDR)    while self.history and ctime - self.history[-1] > 60:      self.history.pop()    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])# 頻率類代碼注釋     # 訪問頻率的邏輯#     #   {'ip地址':[16:13:39,16:13:19,],'ip地址2':[時(shí)間1,時(shí)間2],}#     # (1)取出訪問者ip#     # (2)判斷當(dāng)前ip不在訪問字典里,添加進(jìn)去,并且直接返回True,表示第一次訪問,在字典里,繼續(xù)往下走#     # (3)循環(huán)判斷當(dāng)前ip的列表,有值,并且當(dāng)前時(shí)間減去列表的最后一個(gè)時(shí)間大于60s,把這種數(shù)據(jù)pop掉,這樣列表中只有60s以內(nèi)的訪問時(shí)間,#     # (4)判斷,當(dāng)列表小于3,說明一分鐘以內(nèi)訪問不足三次,把當(dāng)前時(shí)間插入到列表第一個(gè)位置,返回True,順利通過#     # (5)當(dāng)大于等于3,說明一分鐘內(nèi)訪問超過三次,返回False驗(yàn)證失敗#     #(1)取出訪問者ip#     # print(request.META)#     # REMOTE_ADDR 就是訪問者的ip:127.0.0.1#     ip=request.META.get('REMOTE_ADDR')#     import time#     # 獲取當(dāng)前時(shí)間#     ctime=time.time()#     # (2)判斷當(dāng)前ip不在訪問字典里,添加進(jìn)去,并且直接返回True,表示第一次訪問#     if ip not in self.VISIT_RECORD:#       self.VISIT_RECORD[ip]=[ctime,]#       # {'127.0.0.1':[時(shí)間1,時(shí)間1,]}#       return True#     # self.history=[時(shí)間1,時(shí)間1,]#     self.history=self.VISIT_RECORD.get(ip)#     # (3)循環(huán)判斷當(dāng)前ip的列表,有值,并且當(dāng)前時(shí)間減去列表的最后一個(gè)時(shí)間大于60s,把這種數(shù)據(jù)pop掉,這樣列表中只有60s以內(nèi)的訪問時(shí)間,#     while self.history and ctime-self.history[-1]>60:#       self.history.pop()#     # (4)判斷,當(dāng)列表小于3,說明一分鐘以內(nèi)訪問不足三次,把當(dāng)前時(shí)間插入到列表第一個(gè)位置,返回True,順利通過#     # (5)當(dāng)大于等于3,說明一分鐘內(nèi)訪問超過三次,返回False驗(yàn)證失敗#     if len(self.history)<3:#       self.history.insert(0,ctime)#       return True#     else:#       return False            
新聞熱點(diǎn)
疑難解答
圖片精選