【DRF頻率】Python中第三方庫rest_framework的用法
阿新 • • 發佈:2018-12-22
開發平臺的API介面呼叫需要限制其頻率,以節約伺服器資源和避免惡意的頻繁呼叫.
DRF就為我們提供了一些頻率限制的方法.
DRF中的版本、認證、許可權、頻率元件的原始碼是一個流程,且頻率元件再最後執行.
DRF頻率元件原理
·
DRF中的頻率控制基本原理是基於訪問次數和時間的,當然我們也可以通過自己定義的方法來實現.
當請求進來,走到我們的頻率元件時,DRF內部會有一個字典來記錄訪問者的IP.
以這個字典的IP為key,value為一個列表,存放訪問者每次訪問的時間:{PI1: [第三次訪問時間, 第二次訪問時間, 第一次訪問時間, ]}
把每次訪問的最新時間放入列表的最前面,記錄這樣一個數據結構後,通過如下方式限制:
·
如果我們設定的是10秒內只能訪問5次:
- 判斷訪問者的IP是否在這個請求IP的字典裡.
- 保證這個列表裡都是都是最近10秒內訪問的時間.
: 判斷當前請求時間和列表裡最早的(也就是最後一個)請求時間差
: 如果差大於10秒,說明請求不是最近10秒內的,刪除掉最後一個
: 繼續判斷倒數第二個、第三個,直到差小於10秒為止- 判斷列表的長度(即訪問次數)是否大於我們設定的5次.
: 如果大於,則限制其訪問
: 如果小於,則放行,並把時間記錄到列表的最前面
使用自帶的頻率限制類
首先 配置頻率限制類
from rest_framework.throttling import SimpleRateThrottle # 匯入內建的頻率限制類
class DRFThrottle(SimpleRateThrottle): """注意:這裡都是必備的屬性、方法和返回值""" scope = 'WD' def get_cache_key(self, request, view): # 拿IP地址 return self.get_ident(request)
然後 配置檔案
REST_FRAMEWORK = { # 指定頻率限制的類 "DEFAULT_THROTTLE_CLASSES": ['blog.throttle.DRFThrottle'], # WD是scope定義的值,3/m表示每分鐘不能超過3次訪問
"DEFAULT_THROTTLE_RATES": {"WD": "3/m"}, } """ 如果只是想給單個檢視做頻率限制: 則刪除這裡的"DEFAULT_THROTTLE_CLASSES"配置項 並在要做頻率限制的檢視中指定頻率限制類即可 指定語法:throttle_classes = ["頻率限制類", ] """
開始測試.
訪問測試頁面,連續重新整理3次後,可看到:
使用自定義的頻率限制類
首先 自定義頻率限制類
import time VISIT_RECORD = {} # 限制訪問次數的字典 class MyThrottle(): """ 自定義頻率限制類,一分鐘允許訪問5次 注意:自定義頻率限制類中必須要有allow_request和wait方法 前者用於頻率限制的邏輯,後者用於返回限制時間還剩多少秒 """ def __init__(self): self.history = [] def allow_request(self, request, view): """用於限制訪問的邏輯""" # 獲取使用者的IP地址 ip = request.META.get('REMOTE_ADDR') if ip not in VISIT_RECORD: VISIT_RECORD[ip] = [time.time(), ] else: history = VISIT_RECORD[ip] self.history = history history.insert(0, time.time()) # 確保訪問時間在允許範圍之內 while self.history[0] - self.history[-1] > 60: self.history.pop() # 確定訪問次數在允許的範圍內 if len(self.history) >= 5: return False return True def wait(self): """用於返回限制時間還剩多少秒""" return 60 - (self.history[0] - self.history[-1])
然後 配置檔案
REST_FRAMEWORK = { # 指定自定義的頻率限制類 "DEFAULT_THROTTLE_CLASSES": ['blog.throttle.MyThrottle'], } > """ 如果只是想給單個檢視做頻率限制: 則刪除這裡的"DEFAULT_THROTTLE_CLASSES"配置項 並在要做頻率限制的檢視中指定頻率限制類即可 指定語法:throttle_classes = ["頻率限制類", ] """
好了,就到這裡吧.