學習完rest_framework的權限,我們繼續看“節流”功能是如何完成的。
一、 和認證、權限一樣,從dispatch到initial方法,在initial的最後就是運行“節流”校驗的函數(check_throttles)了。
def initial(self, request, *args, **kwargs):
self.format_kwarg = self.get_format_suffix(**kwargs)
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
# 認證
self.perform_authentication(request)
# 權限
self.check_permissions(request)
# 節流
self.check_throttles(request)
二、 check_throttles的過程和權限驗證的過程是相似的,遍歷self.get_throttles()返回的包含節流類的列表,然後執行每一個實例化後的節流類的allow_request方法。
如果節流失敗,則返回True,如果全部節流失敗,則節流驗證通過; 如果節流成功,會執行節流類的wait方法(返回數字類型結果)並將返回結果放進throttle_durations中,等遍歷完畢後,對throttle_durations進行空值排除,尋取最大值,得到duration然後運行self.throttled(request, duration)。
def check_throttles(self, request):
throttle_durations = []
for throttle in self.get_throttles(): # 遍歷self.get_throttles()返回的結果
if not throttle.allow_request(request, self):
throttle_durations.append(throttle.wait())
if throttle_durations:
durations = [
duration for duration in throttle_durations
if duration is not None
]
duration = max(durations, default=None)
self.throttled(request, duration)
- self.get_throttles()的功能就是將self.throttle_classes中的每一個節流類實例化並放進列表中,返回給check_throttles方法。
def get_throttles(self):
return [throttle() for throttle in self.throttle_classes]
三、 throttled方法其實就是拋出了rest_framework.exceptions.Throttled異常,返回數據給前端,告知訪問被節流和禁止訪問的剩餘時間
def throttled(self, request, wait):
raise exceptions.Throttled(wait)
四、 節流類在視圖類的設置(局部)
與認證和權限一樣,通過在視圖類中添加throttle_classes屬性可以爲視圖類添加節流的功能:
from rest_framework.permissions import AllowAny
from rest_framework.authentication import BaseAuthentication
from rest_framework.throttling import SimpleRateThrottle
class MyView(APIView):
authentication_classes = [BaseAuthentication,] # 認證類
permission_classes = [AllowAny,] # 權限類
throttle_classes = [SimpleRateThrottle,] # 節流類
def get(self, request, *args, **kwargs):
…………
rest_framework內置了五種節流類:BaseThrottle、SimpleRateThrottle、AnonRateThrottle、UserRateThrottle、ScopedRateThrottle。
五、 節流類的全局設置
在項目的settings.py中的REST_FRAMEWORK配置項中添加DEFAULT_THROTTLE_CLASSES,可以爲項目設置全局的節流功能。
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["rest_framework.authentication.BaseAuthentication",], # 認證類
"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.AllowAny"], # 權限類
"DEFAULT_THROTTLE_CLASSES": ["rest_framework.permissions.SimpleRateThrottle"] # 節流類
}
六、 自定義節流類
有時候我們需要開發自己的節流功能,所以要自定義一些節流類。節流類必須包含兩個方法:allow_request、wait,前者用於添加節流方法並返回True或False,後者用於提醒用戶剩餘的禁止訪問時間。
class MyThrottle(object):
def allow_request(self, request, view):
return True
def wait(self):
return None