回顧
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