程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

【武sir】django rest framework源碼和實戰_day02(下)

編輯:Python

(0)摘要

# 課程鏈接

4天搞定django rest framework源碼和實戰_哔哩哔哩_bilibili     

# 課程內容

(1)rest framework之權限源碼流程

(2)rest framework之權限的內置類

(3)rest framework之訪問頻率控制基本實現

(4)rest framework之訪問頻率控制源碼流程

(5)rest framework之基於內置類實現訪問頻率控制

(6)rest framework之訪問頻率內容梳理

【補充知識】


(1)rest framework之權限源碼流程

# (1)權限認證的源碼流程,自己寫的。

                1)總之和用戶認證的配置是差不多的。


(2)rest framework之權限的內置類

# (1)內置的權限規則 BasePermission 類

                1)要使用的時候直接 from rest_framework.permissions import BasePermission 即可。下圖是源碼,這裡需要說明一下,今後我們自定義類的時候,一律繼承這個內置類。 這算是一種規范。


# (2)小總結,重點還是看源碼


(3)rest framework之訪問頻率控制基本實現

# (1)訪問控制的思路

                1)為了便於描述,我們直接上武sir 的筆記。假設用戶 C 訪問了服務端 S,且分鐘內只能訪問次,訪問記錄是一個字典,字典的一個字段對應一個用戶的 IP。當 C 訪問的時候,會拿到 C 的 ip 地址並在訪問記錄字典中,生成對應的字段,值是一個列表,列表中記錄了 C 一分鐘內的所有訪問時間(可能是訪問了 1 次,也可能是 3 次)。

                如下圖所示,比如 C 的第一次訪問的時間是 12:10:05(服務端的計時),那麼此時 C 的訪問的列表    : [12: 10: 05] ,如果在 1 分鐘內發生了總共三次的訪問,那麼訪問列表,  :[12:10:07,12:10:06,12: 10: 05]  (可以看到最早訪問在列表的最後,類似隊列)。當第 4 次訪問進來的時候,設此時為 T 時刻(服務端的計時)。服務端會首先讓 T 減去 1 分鐘,記 (T -60s)然後從列表最後的一個時間開始(即逆向),依次和列表的時間比較,記列表最後的那個時間為t (就是最早進來的時間),如果 t > (T - 60s),那麼肯定當前的 T 還在一分鐘內,故而不能訪問;如果依次比較,(T - 60s)比所有時間到大,顯然可以訪問,那麼就直接清空原列表,此時新列表為  : [ T ];其余情況依此類推。【其實真實的時候,可能不只是用 ip。因為 IP 雖然是用戶的唯一標識,但還是可以通過掛代理的方式換 IP 來突破訪問的限制。除非是注冊用戶,這樣子我們存的唯一標識就是用戶名等信息了,當然如果有水軍也沒轍】

                2) 小總結


# (2)基於上述訪問原理的一個小實戰

                直接上代碼,我們依舊是自定義一個節流類,基本的應用方法,也是和前面的一樣的。然後我們基於上面的原理實現了如下的代碼。值得一提的是 wait() 方法是返回告訴用戶還有多久時間才能夠繼續訪問的。具體的局部配置,也是類似認證和權限的套路。【節流這一個和 drf 的思路是一樣的】

# -*- coding=utf-8 -*-
# github: night_walkiner
# csdn: 潘迪仔
import time
VISIT_RECORD = {} # 默認放在緩存的
class VisitThrottle(object):
def __init__(self):
# 初始化
self.history = None
def allow_request(self, request, view):
# (1) 獲取 遠程主機的 ip 地址
# request.META.get("REMOTE_ADDR") 是獲取遠程主機的地址
# 這是drf內置的,也可以使用語句 request._request.META.get("REMOTE_ADDR"),
# 事實上 drf 給我們封裝的 request ,如果某些方法封裝的 request 找不到,就會去 request._request 中找
remote_addr = request.META.get("REMOTE_ADDR")
# (2) 記錄當前訪問的時間
ctime = time.time()
# (3) 判斷遠程 ip 地址是不是在我們的訪問記錄中,如果是第一次訪問,就添加相應的字段
if not VISIT_RECORD.get(remote_addr):
VISIT_RECORD[remote_addr] = [ctime, ]
return True
history = VISIT_RECORD.get(remote_addr)
self.history = history
# (4) 第二次訪問的時候
while history and history[-1] < ctime - 10:
history.pop()
if len(history) < 3:
history.insert(0, ctime)
VISIT_RECORD[remote_addr] = history
return True
return None
def wait(self):
"""這個函數是提示,再等多少秒就能訪問了"""
# 計算剩余的時間
ctime = time.time()
return 60 - (ctime - self.history[-1])


(4)rest framework之訪問頻率控制源碼流程

# (1)我們直接上流程圖把


(5)rest framework之基於內置類實現訪問頻率控制

# (1)內置的訪問頻率控制類

                1)BaseThrottle() 內,如下圖就是我們的內置的基本訪問頻率控制類的源碼,具體的源碼注釋如下。BaseThrottle() 是通過 from rest_framework.throttling import BaseThrottle 的方法來導入的,之後寫自定義的訪問頻率控制規則的時候,可以繼承該類來寫。【另外在 IP 中的代理問題,可以參考一下鏈接:HTTP_X_FORWARDED_FOR獲取到的IP地址_ccfxue的博客-CSDN博客】

                2)SimpleRateThrottle() 類就是 drf 給我們提供的一個較為完善的頻率訪問控制類,事實上就跟我們上面自定義的規則類似,流程也相似。今後我們也可以繼承這個類來進一步的自定義我們的訪問頻率控制。

                3)SimpleRateThrottle() 類的源碼流程解讀。


# (2)基於內置類來實現訪問頻率控制

               1)首先是配置一下全局的配置,即設置 self.rate 的值

                2)那麼視圖類的代碼如下:

                3)上述的是針對匿名用戶的控制,如果是針對於已注冊的用戶。那麼我們也給出相應的配置和源碼。

                視圖類的代碼


關於全局配置的,可以看視頻的後半段的。鏈接如下:

4天搞定django rest framework源碼和實戰_哔哩哔哩_bilibili

(6)rest framework之訪問頻率內容梳理

# (1)內容梳理

                


【補充知識】

#(1)self.__class__.__name__ 的意思

                1)簡單說就是獲得這個類的類名,如果是 list 或者 dict 的話,那麼其實取到的分別就是 list 和 dict。 


【歡迎指正和補充】


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved