Django REST framework之節流組件實例以及源碼流程分析

拋出問題

對訪問的頻率進行控制(固然只是在必定程度上限制,若客服端換IP,瘋狂註冊帳號沒治)python

經過獲取用戶的IP,實現一分鐘內,只能訪問三次。實際生產中應該記錄放在數據庫,或者放在緩存,或者放在文件中等等,我把記錄直接放在這裏,佔用內存不說,還有就是服務端從啓系統的話,記錄全丟失。數據庫

視圖路由與認證權限相同。api

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from rest_framework.throttling import BaseThrottle
 5 from rest_framework.throttling import SimpleRateThrottle
 6 import time
 7 
 8 VIST_RECORD = {}
 9 
10 
11 class VisitThrottle(BaseThrottle):
12 
13     def __init__(self):
14         self.history = None
15 
16     def allow_request(self, request, view):
17 
18         """
19         一分鐘訪問三次最多
20         判斷是否能夠繼續訪問,頻率是否達到最大
21         :param request:
22         :param view:
23         :return: True 能夠繼續訪問 False表示訪問頻率過高要被限制
24         1.獲取用戶IP
25         """
26         remote_addr = request.META.get('REMOTE_ADDR')
27         ctime = time.time()
28         if remote_addr not in VIST_RECORD:
29             VIST_RECORD[remote_addr] = [ctime,]
30             return True
31         history = VIST_RECORD.get(remote_addr)
32         self.history = history
33         while history and history[-1] < ctime - 60:
34             history.pop()
35 
36         if len(history) < 3:
37             history.insert(0, ctime)
38             return True
39 
40     def wait(self):
41         """
42         還須要等多久才能被訪問
43         :return:
44         """
45         ctime = time.time()
46         return 60 - (ctime - self.history[-1])

固然內置的頁幫咱們寫了這些環節,直接獲取過來用便可緩存

 1 class VisitThrottle(SimpleRateThrottle):
 2     scope = "Baidu"
 3 
 4     def get_cache_key(self, request, view):
 5         return self.get_ident(request)
 6 
 7 
 8 class UserThrottle(SimpleRateThrottle):
 9     """
10     根據當前登陸用戶的訪問次數限制
11     """
12     scope = "BaiduUser"
13 
14     def get_cache_key(self, request, view):
15         return request.user.username

全局配置:ide

 1 REST_FRAMEWORK = {
 2     # 認證
 3     'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.auth.Authticate', ],
 4     # 'DEFAULT_AUTHENTICATION_CLASSES': [],  # AnonymousUser None配置文件中有
 5     # 'UNAUTHENTICATED_USER': lambda: '匿名用戶',
 6     # 'UNAUTHENTICATED_USER': None,
 7     # 'UNAUTHENTICATED_TOKEN': None,
 8     # 權限
 9     'DEFAULT_PERMISSION_CLASSES': ['api.utils.permission.Mypermission'],
10     # 節流 訪問頻率控制
11     "DEFAULT_THROTTLE_CLASSES": ['api.utils.throttle.VisitThrottle', ],
12     "DEFAULT_THROTTLE_RATES": {
13         "Baidu": '3/m',
14         "BaiduUser": '10/m',
15     }
16 
17 }

局部配置:spa

1 throttle_classes = [VisitThrottle, ]

總結:本身定義節流類,在類中實現allow_request(都是這樣子若沒寫前面幾個組件都是拋錯,看基類),wait兩方法,固然wait能夠不用寫,固然看需求吧!rest

源碼流程分析

 APIView的dispatch---->封裝request----->initial----->self.check_throttles(request)----->allow_request(request, self)(兩種狀況:True訪問頻率未達到最高次數,Flase訪問頻率已經達到最大的次數)code

內置節流類

BaseThrottle allow_request主邏輯  get_ident獲取IP wait超過次數須要多久恢復blog

SimpleRateThrottle 適用 跟我上面實現思路差很少 在settings中配置scope便可快捷內存

AnonRateThrottle 針對匿名用戶的 配置scope = 'anon'

UserRateThrottle scope = 'user'

ScopedRateThrottle scope_attr = 'throttle_scope'

相關文章
相關標籤/搜索