2020-12-14 drf 之頻率限制

回顧

1啥供、認(rèn)證:判斷用戶是否登錄

2撮执、登錄功能:(一個(gè)大表拆成一對(duì)一的兩個(gè)小表,其實(shí)叫垂直分表)

-update_or_create()

3沙兰、認(rèn)證類

-寫一個(gè)類氓奈,繼承BaseAuthentication
-重寫authenticate
-在authenticate內(nèi)部做認(rèn)證(request對(duì)象)
    -request中取出token
    -認(rèn)證通過(guò),返回會(huì)None僧凰,或者有兩個(gè)元素的元組(user探颈,token),當(dāng)配置有等多個(gè)認(rèn)證類時(shí),前幾個(gè)如果有返回值那么后面的認(rèn)賬類就不走了训措,有返回值認(rèn)證直接就結(jié)束了
    -認(rèn)證失敗:AuthenticationFailed中有錯(cuò)誤信息

4光羞、使用認(rèn)證類

-局部使用
    -視圖類上配置
-全局使用
    -配置文件中配置

5绩鸣、配置信息的查找順序:先從視圖類中找(局部配置)--->用戶項(xiàng)目的配置文件(全局配置)-->drf默認(rèn)的配置文件(不配置)

6、認(rèn)證源碼分析

-所有drf的請(qǐng)求纱兑,都會(huì)執(zhí)行APIView的dispatch
-Request對(duì)象中有個(gè)authenticators屬性呀闻,他是我們?cè)谝晥D類中配置的認(rèn)證類的對(duì)象,放到了列表中
-只要通過(guò)了認(rèn)證
    request.user  # 就是當(dāng)前登錄用戶潜慎,在認(rèn)證類中返回

7捡多、權(quán)限的使用

-寫一個(gè)類,繼承BasePermission
-重寫has_permission
-在has_permission內(nèi)部做權(quán)限控制(request對(duì)象)
    -request中取出token
    -認(rèn)證通過(guò)铐炫,返回True
    -認(rèn)證失敗垒手,返回False

8、源碼分析

-APIView的dispatch---》APIView的initial---》APIView的check_permissions(request)
for permission in self.get_permissions(): # 權(quán)限類對(duì)象放到列表中
    if not permission.has_permission(request, self):  # 沒(méi)有權(quán)限類結(jié)果就是說(shuō)明沒(méi)有權(quán)限倒信,就會(huì)走下面的代碼科贬,返回錯(cuò)誤信息
        self.permission_denied(
             request,
             message=getattr(permission, 'message', None),  # 通過(guò)反射拿到的自定義權(quán)限類中配置的錯(cuò)誤信息,配置的時(shí)中文的那顯示就是中文的
             code=getattr(permission, 'code', None)
            )

9鳖悠、錯(cuò)誤信息中文顯示

在權(quán)限類中加一個(gè)message=字符串

今日內(nèi)容

1榜掌、權(quán)限源碼分析

    -APIView的dispatch---》APIView的initial---》APIView的check_permissions(request)
    for permission in self.get_permissions(): # 權(quán)限類對(duì)象放到列表中
        if not permission.has_permission(request, self):  # 沒(méi)有權(quán)限類結(jié)果就是說(shuō)明沒(méi)有權(quán)限优妙,就會(huì)走下面的代碼,返回錯(cuò)誤信息
            self.permission_denied(
                 request,
                 message=getattr(permission, 'message', None), # 通過(guò)反射拿到的自定義權(quán)限類中配置的錯(cuò)誤信息憎账,配置的時(shí)中文的那顯示就是中文的
                 code=getattr(permission, 'code', None)
                )
錯(cuò)誤信息中文顯示
    在權(quán)限類中加一個(gè)message=字符串

2套硼、模型層choice字段使用(重點(diǎn))

-1、模型表:Student表胞皱,寫接口應(yīng)該選擇繼承那個(gè)視圖類
-2熟菲、推薦使用自動(dòng)生成路由的方式(繼承ViewSetMixin及它的子類)
-3、但是目前來(lái)說(shuō)朴恳,先實(shí)現(xiàn)功能抄罕,以后熟悉了再選擇合適的視圖類繼承

-4、choice的使用
    -再模型類中使用
    sex=models.SmallIntegerField(choices=((1,'男'),(2,'女'),(3,'位置'),default=1)
    -在視圖類中于颖,在序列化類中寫
        -get_字段名_display()的方法呆贿,該方法獲得choice字段對(duì)應(yīng)的數(shù)據(jù),這是一個(gè)方法森渐,是隱藏在模型類中的
        只要寫了choice做入,配好關(guān)系了,該對(duì)象就會(huì)有個(gè) get_字段名_display()的方法

3同衣、自定義頻率類

-1 限制某個(gè)人竟块,某個(gè)ip的訪問(wèn)頻次

-2 自定義頻率類及使用
from rest_framework.throttling import BaseThrottle
class MyThrottle(BaseThrottle):
    VISIT_RECORD = {}  # 存用戶訪問(wèn)信息的大字典
    def __init__(self):
        self.history = None
    def allow_request(self,request,view):
        # 根據(jù)ip進(jìn)行頻率限制,每分鐘只能訪問(wèn)3次
        # 限制的邏輯
        '''
        #(1)取出訪問(wèn)者ip
        #(2)判斷當(dāng)前ip不在訪問(wèn)字典里耐齐,添加進(jìn)去浪秘,并且直接返回True,表示第一次訪問(wèn),在字典里埠况,繼續(xù)往下走
        #(3)循環(huán)判斷當(dāng)前ip的列表耸携,有值,并且當(dāng)前時(shí)間減去列表的最后一個(gè)時(shí)間大于60s辕翰,把這種數(shù)據(jù)pop掉夺衍,這樣列表中只有60s以內(nèi)的訪問(wèn)時(shí)間,
        #(4)判斷喜命,當(dāng)列表小于3沟沙,說(shuō)明一分鐘以內(nèi)訪問(wèn)不足三次,把當(dāng)前時(shí)間插入到列表第一個(gè)位置壁榕,返回True矛紫,順利通過(guò)
        #(5)當(dāng)大于等于3,說(shuō)明一分鐘內(nèi)訪問(wèn)超過(guò)三次护桦,返回False驗(yàn)證失敗
        '''
        # (1)取出訪問(wèn)者ip
        # print(request.META)
        ip = request.META.get('REMOTE_ADDR')
        import time
        ctime = time.time()
        # (2)判斷當(dāng)前ip不在訪問(wèn)字典里含衔,添加進(jìn)去,并且直接返回True,表示第一次訪問(wèn)
        if ip not in self.VISIT_RECORD:
            self.VISIT_RECORD[ip] = [ctime, ]
            return True
        self.history = self.VISIT_RECORD.get(ip)
        # (3)循環(huán)判斷當(dāng)前ip的列表,有值贪染,并且當(dāng)前時(shí)間減去列表的最后一個(gè)時(shí)間大于60s缓呛,把這種數(shù)據(jù)pop掉,這樣列表中只有60s以內(nèi)的訪問(wèn)時(shí)間杭隙,
        while self.history and ctime - self.history[-1] > 60:
            self.history.pop()
        # (4)判斷哟绊,當(dāng)列表小于3,說(shuō)明一分鐘以內(nèi)訪問(wèn)不足三次痰憎,把當(dāng)前時(shí)間插入到列表第一個(gè)位置票髓,返回True,順利通過(guò)
        # (5)當(dāng)大于等于3铣耘,說(shuō)明一分鐘內(nèi)訪問(wèn)超過(guò)三次洽沟,返回False驗(yàn)證失敗
        if len(self.history) < 3:
            self.history.insert(0, ctime)
            return True
        else:
            return False

    def wait(self):
        # 還剩多長(zhǎng)時(shí)間能訪問(wèn)
        import time
        ctime = time.time()
        return 60 - (ctime - self.history[-1])

-3 使用
    -局部使用
    -全局使用

4、內(nèi)置平頻率使用

-1 使用
    -局部使用
        throttle_classes = [auth.MyThrottle,]
    -全局使用
        REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_CLASSES':['app01.auth.MyThrottle',],
        }

-2 內(nèi)置頻率類
    BaseThrottle:基類
    AnonRateThrottle:限制匿名用戶的訪問(wèn)次數(shù)
    SimpleRateThrottle:咱們自定義擴(kuò)寫它
    ScopedRateThrottle: 限制用戶對(duì)于每個(gè)視圖的訪問(wèn)頻次蜗细,使用ip或user id
    UserRateThrottle:限制登錄用戶訪問(wèn)次數(shù)
-3 擴(kuò)展內(nèi)置頻率類(重點(diǎn)記遵刹佟)
    -寫一個(gè)類,繼承SimpleRateThrottle
    class MySimpleThrottle(SimpleRateThrottle):
        scope = 'xxx'
        def get_cache_key(self, request, view):
            #以ip限制
            return self.get_ident(request)
    -setting.py中配置
        REST_FRAMEWORK = {
            'DEFAULT_THROTTLE_RATES' : {
                'xxx':'10/m'# key跟scope對(duì)應(yīng)炉媒,value是一個(gè)時(shí)間
            }
        }
    -局部使用和全局使用
-4 源碼分析
    -繼承SimpleRateThrottle---》allow_request(跟咱么寫的一樣)


-5 其它內(nèi)置頻率類
    -限制未登錄用戶的頻率(AnonRateThrottle)(根據(jù)ip限制)
        -使用:
            -局部使用踪区,全局使用
            -setting.py中配置
               'DEFAULT_THROTTLE_RATES' : {
                    'anon':'1/m'
                }
    -限制登錄用戶訪問(wèn)次數(shù)UserRateThrottle(根據(jù)用戶id限制)
        -使用:
        -局部使用,全局使用
        -setting.py中配置
        'DEFAULT_THROTTLE_RATES' : {
            'user':'1/m'
        }
    -ScopedRateThrottle(有興趣看一下吊骤,沒(méi)有就不看了)

5 內(nèi)置缎岗,第三方過(guò)濾功能(次重點(diǎn))

-1 過(guò)濾:篩選查詢結(jié)果
-2 內(nèi)置篩選的使用
    -在視圖類中配置
        filter_backends =[SearchFilter,]
        search_fields=('name',) # 表模型中的字段
    -查詢的時(shí)候
        http://127.0.0.1:8000/students/?search=e
                search后面的參數(shù)可以寫全,也可也這樣就是模糊匹配了白粉,如果過(guò)濾的是兩個(gè)字段传泊,那么就是兩個(gè)字段公用一個(gè)查詢條件,比如寫的是search=1蜗元,
                查詢字段是name和age或渤,那么查出來(lái)的就是name中有1和age中有1的數(shù)據(jù),還可以search=e,1,那么就是篩選兩個(gè)條件奕扣,每個(gè)字段都篩選這兩個(gè)條件。
                不夠智能掌敬。但是也可以寫全了取篩選惯豆,就比較精準(zhǔn)了,比如:search=egon,18

-3 第三方擴(kuò)展的過(guò)濾功能
    -pip3 install django-filter  :最新版本(2.4.0)要跟django2.2以上搭配

    -在視圖類中配置
        filter_backends =[DjangoFilterBackend,]
        filter_fields=['name','age']
    -查詢的時(shí)候
        http://127.0.0.1:8000/students/?name=lqz&age=18

6 排序功能(次重點(diǎn))

-在視圖類中配置
    filter_backends =[OrderingFilter,]
    ordering_fields=['id','age']
-查詢的時(shí)候
    http://127.0.0.1:8000/students/?ordering=-age  # 加-號(hào)是反向也就是降序排序奔害,不加就是升序排序


 ### 過(guò)濾后再排序
  -在視圖類中配置
    filter_backends = [OrderingFilter,DjangoFilterBackend]
    ordering_fields = ('id', 'age')
    filter_fields=['name','age']
  -查詢的時(shí)候
    http://127.0.0.1:8000/students/?name=lqz&age=19&ordering=-age,-id
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末楷兽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子华临,更是在濱河造成了極大的恐慌芯杀,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異揭厚,居然都是意外死亡却特,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門筛圆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)裂明,“玉大人,你說(shuō)我怎么就攤上這事太援∶龌蓿” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵提岔,是天一觀的道長(zhǎng)仙蛉。 經(jīng)常有香客問(wèn)我,道長(zhǎng)碱蒙,這世上最難降的妖魔是什么荠瘪? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮振亮,結(jié)果婚禮上巧还,老公的妹妹穿的比我還像新娘。我一直安慰自己坊秸,他們只是感情好麸祷,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著褒搔,像睡著了一般阶牍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上星瘾,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天走孽,我揣著相機(jī)與錄音,去河邊找鬼琳状。 笑死磕瓷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的念逞。 我是一名探鬼主播困食,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼翎承!你這毒婦竟也來(lái)了硕盹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤叨咖,失蹤者是張志新(化名)和其女友劉穎瘩例,沒(méi)想到半個(gè)月后啊胶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡垛贤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年焰坪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片南吮。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡琳彩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出部凑,到底是詐尸還是另有隱情露乏,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布涂邀,位于F島的核電站瘟仿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏比勉。R本人自食惡果不足惜劳较,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浩聋。 院中可真熱鬧观蜗,春花似錦、人聲如沸衣洁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)坊夫。三九已至砖第,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間环凿,已是汗流浹背梧兼。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留智听,地道東北人羽杰。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像到推,于是被迫代替她去往敵國(guó)和親忽洛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容