Django REST Framework之頻率限制的使用
開(kāi)放平臺(tái)的API接口調(diào)用需要限制其頻率,以節(jié)約服務(wù)器資源和避免惡意的頻繁調(diào)用
使用
自定義頻率限制組件:utils/thottle.py
class MyThrottle(BaseThrottle):
def __init__(self):
self.history = None
def allow_request(self, request, view):
# 實(shí)現(xiàn)限流的邏輯
# 以IP限流
# 訪(fǎng)問(wèn)列表 {IP: [time1, time2, time3]}
# 1, 獲取請(qǐng)求的IP地址
ip = request.META.get("REMOTE_ADDR")
# 2,判斷IP地址是否在訪(fǎng)問(wèn)列表
now = time.time()
if ip not in VISIT_RECORD:
# --1, 不在 需要給訪(fǎng)問(wèn)列表添加key,value
VISIT_RECORD[ip] = [now,]
return True
# --2 在 需要把這個(gè)IP的訪(fǎng)問(wèn)記錄 把當(dāng)前時(shí)間加入到列表
history = VISIT_RECORD[ip]
history.insert(0, now)
# 3, 確保列表里最新訪(fǎng)問(wèn)時(shí)間以及最老的訪(fǎng)問(wèn)時(shí)間差 是1分鐘
while history and history[0] - history[-1] > 60:
history.pop()
self.history = history
# 4,得到列表長(zhǎng)度,判斷是否是允許的次數(shù)
if len(history) > 3:
return False
else:
return True
def wait(self):
# 返回需要再等多久才能訪(fǎng)問(wèn)
time = 60 - (self.history[0] - self.history[-1])
return time
views.py
class TestThrottle(APIView):
throttle_classes = [MyThrottle, ]
def get(self, request, *args, **kwargs):
pass
- allow_request() 方法內(nèi)定義頻率控制的實(shí)現(xiàn)
- wait() 方法的返回值代表了距離下次允許訪(fǎng)問(wèn)還剩多久,單位:秒
全局使用
同樣,需要配置setttings文件
EST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": [] # 默認(rèn)的權(quán)限類(lèi)
}
使用REST Framework提供的頻率控制組件
DRF提供了四種頻率控制組件:
- SimpleRateThrottle
- AnonRateThrottle
- UserRateThrottle
- ScopedRateThrottle
以SimpleRateThrottle為例:
settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES':['api.utils.mythrottle.UserThrottle',]
'DEFAULT_THROTTLE_RATES': {
'未認(rèn)證用戶(hù)': '10/m',
'已認(rèn)證用戶(hù)': '100/h',
},
}
utils.thorttle.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import exceptions
from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
scope = "未認(rèn)證用戶(hù)"
def get_cache_key(self, request, view):
return self.get_ident(request)
class UserThrottle(SimpleRateThrottle):
scope = "已認(rèn)證用戶(hù)"
def get_cache_key(self, request, view):
return request.user # 認(rèn)證通過(guò)后,認(rèn)證方法authenticate的返回值之一
views.py
class TestThrottle(APIView):<br> # 這樣設(shè)置后,節(jié)流功能就會(huì)使用VisitThrottle類(lèi),而不會(huì)使用UserThrottle類(lèi) throttle_classes = [VisitThrottle,] def get(self, request, *args, **kwargs):
這里使用的節(jié)流類(lèi)是繼承了SimplePateThrottle類(lèi),而這個(gè)類(lèi)利用了django內(nèi)置的緩存來(lái)存儲(chǔ)訪(fǎng)問(wèn)記錄。通過(guò)全局節(jié)流設(shè)置,所有的視圖類(lèi)默認(rèn)是使用UserThrottle類(lèi)進(jìn)行節(jié)流,如果不想使用默認(rèn)的類(lèi)就自定義給throttle_classes屬性變量賦值,如:“throttle_classes = [VisitThrottle,]”。
源碼分析
1.為什么會(huì)使用“scope”屬性變量,它有什么用?

由內(nèi)置接口代碼基本結(jié)構(gòu)中可以看到,視圖類(lèi)TestThrottle繼承了SimpleRateThrottle類(lèi),跳轉(zhuǎn)到這個(gè)類(lèi)中,就可以看到scope屬性變量。


由“THROTTLE_RATES[self.scope]”知,scope一定是一個(gè)key值,而THROTTLE_RATES不就是在配置文件中所設(shè)置的變量嗎?所以說(shuō)scope代表的就是“未認(rèn)證用戶(hù)”和“已認(rèn)證用戶(hù)”這兩個(gè)key值,而這兩個(gè)key值代表的就是不同的節(jié)流方案。返回值就這這兩個(gè)key值所對(duì)應(yīng)的value值,具體是哪一個(gè),那就看視圖類(lèi)TestTrottle中對(duì)scope屬性變量的值是什么了,如果這個(gè)scope值不存在,就會(huì)拋出異常。
2.為什么會(huì)使用“get_cache_key”方法?該方法的返回值是什么?
在分析get_cache_key方法前,先分析一下SimpleRateThrottle類(lèi):

cache = default_cache 它表示的就是存儲(chǔ)用戶(hù)訪(fǎng)問(wèn)記錄的緩存,而這個(gè)緩存正是django默認(rèn)的緩存。
get_rate 方法,前面已經(jīng)說(shuō)過(guò)了,是用來(lái)獲取節(jié)流方式的。

parse_rate方法,解析節(jié)流方式

allow_request方法,就是跟在自定義節(jié)流方法一樣,是實(shí)現(xiàn)節(jié)流算法的。之所以會(huì)用內(nèi)置節(jié)流方法,就是因?yàn)樵谶@里,已經(jīng)實(shí)現(xiàn)了節(jié)流算法。

wait方法,就是跟在自定義節(jié)流類(lèi)中的wait方法一樣,返回提示用戶(hù)還有多長(zhǎng)時(shí)間就可以再次訪(fǎng)問(wèn)了。

通過(guò)初始化方法,獲取并解析好要使用的節(jié)流方式,供allow_request方法使用。

通過(guò)調(diào)用check_throttles方法,來(lái)調(diào)用allow_request方法,由上面關(guān)于allow_request截圖來(lái)看,要完成它的功能,就必須通過(guò)get_cache_key方法獲取到當(dāng)前用戶(hù)的唯一標(biāo)識(shí),所以get_cache_key應(yīng)該返回唯一標(biāo)識(shí)。

get_cache_key 方法,這就是在視圖類(lèi)TestThrottle中重寫(xiě)的方法。由上圖可知,該方法是必須重寫(xiě)的,不然就會(huì)拋出異常。
3.為什么會(huì)使用“throttle_classes”屬性變量,它有什么用?

通過(guò)查看dispatch方法中的intial方法可以看到調(diào)用的節(jié)流方法“check_throttles”。

這個(gè)for循環(huán)返回的一定是一個(gè)列表,類(lèi)似于認(rèn)證和授權(quán)的源碼,那么這個(gè)列表一定是保存節(jié)流類(lèi)的列表。

get_throttles方法返回的是一個(gè)列表生成式,而這里的throttle_classes就是在視圖類(lèi)TestThrottle中使用的,該變量就保存節(jié)流類(lèi)對(duì)象。
4.“DEAFULT_THROTTLE_CLASSES”從哪里來(lái)?有什么用?

通過(guò)throttle_classes屬性變量,跳轉(zhuǎn)到該圖,可以看到配置文件中說(shuō)的“DEFAULT_THROTTLE_CLASSES”,它是用來(lái)通過(guò)配置文件settings來(lái)對(duì)全局節(jié)流類(lèi)進(jìn)行配置,功能等價(jià)于throttle_classes屬性變量
5.“DEAFULT_THROTTLE_RATES”從哪里來(lái)?有什么用?

由SimpleRateThrottle類(lèi)和上文對(duì)scope屬性變量的分析可知,THROTTLE_RATES就是為了存儲(chǔ)在配置文件中設(shè)置的不同的節(jié)流方法的。
綜上所述,可以看出,在利用內(nèi)置節(jié)流接口時(shí),通過(guò)配置文件settings的設(shè)置和提供該接口所需的用戶(hù)唯一標(biāo)識(shí)外,不需要我們做再多的操作,這就形成了我們上文寫(xiě)的內(nèi)置接口代碼基本結(jié)構(gòu)的樣式。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- django rest framework之請(qǐng)求與響應(yīng)(詳解)
- Django rest framework基本介紹與代碼示例
- Django rest framework實(shí)現(xiàn)分頁(yè)的示例
- 淺談Django REST Framework限速
- Django-Rest-Framework 權(quán)限管理源碼淺析(小結(jié))
- django-rest-framework解析請(qǐng)求參數(shù)過(guò)程詳解
- Django rest framework工具包簡(jiǎn)單用法示例
- django rest framework 實(shí)現(xiàn)用戶(hù)登錄認(rèn)證詳解
- Django Rest framework權(quán)限的詳細(xì)用法
- Django REST framework 視圖和路由詳解
相關(guān)文章
python實(shí)現(xiàn)三種隨機(jī)請(qǐng)求頭方式
這篇文章主要介紹了python實(shí)現(xiàn)三種隨機(jī)請(qǐng)求頭方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
python中@contextmanager裝飾器的用法詳解
這篇文章主要介紹了python中@contextmanager裝飾器的用法詳解,@contextmanager 的作用就是我們可以把一個(gè)非自定義類(lèi)改成一個(gè)上下文管理器,需要的朋友可以參考下2023-07-07
在實(shí)驗(yàn)中需要自己構(gòu)造單獨(dú)的HTTP數(shù)據(jù)報(bào)文,而使用SOCK_STREAM進(jìn)行發(fā)送數(shù)據(jù)包,需要進(jìn)行完整的TCP交互。因此想使用原始套接字進(jìn)行編程,直接構(gòu)造數(shù)據(jù)包,并在IP層進(jìn)行發(fā)送,即采用SOCK_RAW進(jìn)行數(shù)據(jù)發(fā)送。使用SOCK_RAW的優(yōu)勢(shì)是,可以對(duì)數(shù)據(jù)包進(jìn)行完整的修改,可以處理IP層上的所有數(shù)據(jù)包,對(duì)各字段進(jìn)行修改,而不受UDP和TCP的限制。2014-02-02
Python開(kāi)啟線(xiàn)程,在函數(shù)中開(kāi)線(xiàn)程的實(shí)例
今天小編就為大家分享一篇Python開(kāi)啟線(xiàn)程,在函數(shù)中開(kāi)線(xiàn)程的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-02-02
Python內(nèi)建屬性getattribute攔截器使用詳解
這篇文章主要為大家介紹了Python內(nèi)建屬性getattribute攔截器使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Django token 生成與驗(yàn)證的實(shí)現(xiàn)
本文主要介紹了Django token 生成與驗(yàn)證的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04
python動(dòng)態(tài)進(jìn)度條的實(shí)現(xiàn)代碼
有時(shí)候我們需要使用print打印工作進(jìn)度,正常使用print函數(shù)會(huì)導(dǎo)致刷屏的現(xiàn)象,本文通過(guò)實(shí)例代碼給大家介紹python動(dòng)態(tài)進(jìn)度條的實(shí)現(xiàn)方法,感興趣的朋友跟隨小編一起看看吧2019-07-07
python防止隨意修改類(lèi)屬性的實(shí)現(xiàn)方法
這篇文章主要介紹了python防止隨意修改類(lèi)屬性的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Python Numpy庫(kù)datetime類(lèi)型的處理詳解
這篇文章主要介紹了Python Numpy庫(kù)datetime類(lèi)型的處理詳解,Python中自帶的處理時(shí)間的模塊就有time 、datetime、calendar,另外還有擴(kuò)展的第三方庫(kù),如dateutil等等。。當(dāng)我們用NumPy庫(kù)做數(shù)據(jù)分析時(shí),如何轉(zhuǎn)換時(shí)間呢?需要的朋友可以參考下2019-07-07

