模型操作也就是model類提供的操作能力,一般操作資料無非就是增删改查,CRUD,要學會在django中如何操作,提供了一個orm,這個orm提供了操作的東西,叫管理器對象,管理器對象是一個很特别的類,這個類不能直接調用,這個執行個體是捆綁在控件的model對象上的。
自己建立可以替換,也可以多替換幾個

orm的操作就是将增删改查所有的方法操作換成sql語句,這個語句是交給orm來做的,orm更在乎對象和關系,,比如用外鍵描述關系。比如一對一,多對多。
對象是指面向對象的對象,用類和執行個體的方式描述大千世界,資料庫是用關系模型來描述世界.
類對應表,類屬性對應表字段。一行行記錄對應一個個執行個體
操作和sqlalchemy很像,都是懶惰的方式,如果不使用就不查,減輕對資料庫的負擔,這樣就讓資料庫的更多時間給别人使用。查詢完會緩存,緩存在資料集裡。
也可以使用第三方,把有意義的資料存放到裡面進行緩存,redis可以設定緩存多長時間,或者到什麼時候清除
切片也很懶惰,不用也不查,切片跟limit和offset語句是對應起來的,但是之間有個計算關系
過濾器,就是all,filter,一般很少用all,查詢 了objects.filter用的更多,後面再做切片,用filter的時候小于大于成了問題,不能用了,是以提供了新的文法lookup表達式。
使用主鍵的時候可以使用PK這個值。
提供了一些查詢單個值的方式,get隻能得到1個對象,沒有或者傳回多條都會抛出異常。
first,last,exist用的相對較少
字段查詢表達式,一般放在get,條件,filter,或者排除,排除相當于filter取反,這裡都需要一個條件
一般屬性名和字段名一緻,省的出現問題,一般字段名不用下劃線什麼,不推薦拼音縮寫,除非是國标(有些國家标準字段隻能是拼音首字母),否則不要這麼做
嚴格等于,轉換出來就是哪個字段等于什麼
字元串誰包含了誰,相當于like ‘%xx%’,字段__contains=
左字首比對,字尾比對
是不是為null,
i是ignore忽略大小寫比對
in什麼就寫一個清單,告訴他必須是這麼個東西
大于等于gt,gte,小于等于lt,lte
可以将日期類型的提取出一部分來比較,幫你把年份提取出來做相應處理
在and條件下,現在‘’或‘’沒辦法寫
把id=1或者id=2的拿到
這裡不認or,就隻能借助q對象了,and or都用q對象來解決你放入的參數,并列,and,or,取反
Q對象在models下
user也在models下
試試這種方式行不行
好像沒有達到想要的目的
這裡的or并不是給資料庫真正用的,有前面可以先短路了,這是python直接取or了,該短路短路了
引入了|号,在sqlalchemy可以直接拿來用
這樣就ok了,這裡的or是python的邏輯表達式,不是django 的orm的表示式,要使用就用運算符重載|
&代表and
這樣就成功了
這樣其實比filter好,借助Q對象,和& 和|符号,結合起來寫非常複雜的邏輯表達式,這樣會更好點
~代表not
一個表達式可以不要Q對象
寫這樣試試
就出問題了
寫成這樣
取反
可以使用&|和Q對象來構造複雜的邏輯表達式,可以用在filter,get,
過濾器可以使用一個或多個Q對象,過濾器函數就是filter,get
如果混用關鍵字參數和Q對象,那麼Q對象必須位于關鍵字參數的前面。所有參數都将and在一起,一般不要混寫,直接上去先寫Q對象。
簡單的用lookup表達式,複雜的用Q對象&and|或者~取反
注冊接口設計完善
http協定是無狀态的(同樣用戶端連接配接兩次伺服器,伺服器依然以為是兩個人,無法區分),為了讓伺服器知道你是同一個,cookie會在浏覽器發起請求的時候request header裡帶有cookie,這個cookie内部又寫了個值,誰等于誰
、
cookie定義了好幾個鍵值對,誰等于誰;冒号 誰等于誰,等于字典套字典
這個值是來自于setcookie,伺服器要給浏覽器端發,第一次請求來的時候,伺服器跟你商量放一個cookie值,在你請求響應的時候把cookie帶過來
伺服器在response header頭裡放了set-cookie,這個cookie值可以不止一個值
把這些cookie都注入到了浏覽器端,當浏覽器再對這個域名發起請求的時候,如果cookie還沒過期,浏覽器就不清理,cookie還可以使用,當你對這個域名再次發起請求的時候,就會把這個cookie帶上
就會把這個cookie,塞到請求封包的cookie部分
有一個特殊的cookie叫sessionid,這個cookie比較特殊,指的是跟伺服器建立連接配接後,往往動态伺服器會專門給這次會話生成一個session對象,這個session裡如何區分session對象,就靠這個id,每一個建立的會話都要配置設定一個session,這個session都有一個唯一的id,這個id就是sessionid,當你第一次與伺服器建立連接配接後,伺服器就會response,除了給你set-cookie,還會塞入sessionid。
将sessionid發給你,這個sessionid是解決動态伺服器之間互動的,不允許用戶端随意進行修改,這個sessionid也是cookie,當我們的用戶端發起請求的時候,就會将這個cookie裡的sessionid和其他set-cookie裡的發過來的cookie一并帶入請求頭的cookie部分,然後将這些值全部發給伺服器,伺服器就可以獲得這個cookie。
在觀察request對象的時候,内部看到幾個值,get,post,cookie,和meta,get是用來放查詢字元串的,post是把表單傳回去,body傳的資料都在body裡,cookie裡就是拿到的cookie值,在請求頭中發送的cookie值,這個cookie是用來解決無狀态的問題。
實際上僅僅靠cookie還不能知道你是誰,發一個csrftoken是解決安全的問題的,但還不知道你是誰。如何确定你是誰,連結之後,伺服器會為每一個連結建立一個session對象,就是會話,也就是浏覽器和伺服器建立了一個會話連結,注意這個會話連結有可能斷開了。
會話是會話,但是有可能tcp連結已經斷開了,因為是短連接配接,會話和連結并不能一一對應,再次請求伺服器相當于再搭了一個tcp橋,但是在伺服器端有一個session對象,如何知道建立的連結就是上次的人,就要看浏覽器的cookie裡帶不帶sessionid,如果帶了sessionid,就查一下自己的表,發現sessionid存在,就繼續。
當你第一次去通路伺服器的時候,伺服器就蹦出框來,通路需要登入,登入失敗,網站不理你,登入成功就會往你session裡加東西,session裡塞的東西就可以辨別你是誰,這個session實際上是一個資料結構,裡面有個屬性其實就是id,id唯一,代表這一次和某個浏覽器的會話,這個浏覽器再次通路過來的時候,伺服器就會查sessionid
等于建立一個關系,動态網頁技術往往在server端有session管理機制,session管理會為每個浏覽器通路的時候,發一個唯一id,稱為sessionid,為了下一次能帶過來sessionid辨識身份,就使用了cookie,實際上這個sessionid頒發回去的時候,必須在第一次通路完要寫有一個set-cookie,這個浏覽器收到響應後,在cookie裡就有sessionid了。
浏覽器過了一會給同一台server發請求,如果cookie沒過期就會帶上,cookie是跟域名相關的,發往這個伺服器,這個伺服器會在它的session大表裡去找,找這個sessionid在不在,假設sessionid還在,說明 就是上次通路的人,就把無狀态的問題解決掉了。
用cookie加上session就可以完成無狀态的确認,不用sessionid也可以,自己寫個特殊的cookie也可以,但是session本來就是這個機制,沒必要自己去實作一套了,當你去通路伺服器,伺服器會建立會話,給這個會話發一個唯一 sessionid,将sessionid會通過cookie的方式,response給你,下回通過cookie,帶上這個sessionid才能确認身份。
session和cookie機制用來解決無狀态的
session是和域名相關的,通過域名通路同一個網站的時候就會将這個域名帶上,發往伺服器端,浏覽器會自動清楚過期cookie。
浏覽器現在第一次通路網站,浏覽之後,會把sessionid帶上,還有其他cookie值。但是這個人(浏覽器都有清除cookie和曆史記錄),清除了,再通路網站的時候,server就不認識你了。sessionid沒了就沒法判斷。
server會認為你是新的連結重新發一個sessionid
最傳統的驗證,當你第一次通路,會發一個sessionid,表示你兩會話比不過期就可以一直用,如果你登入成功,在session可以再放一個id,比如login:使用者id。當你登入成功發現session是一樣的,确認無誤剛才登入過,還會查目前session大集合裡還有什麼屬性,還有login=true或者userid,這時候就可以不讓你登入了,直接跳到使用者操作界面
、
session還有一種機制,過期機制。
sessionid是非常特殊的cookie,不會長久儲存,一般浏覽器關了就清除掉了,sessionid丢了,對方就不認你了,但是這麼操作,伺服器端會有很多廢掉的 session。session可以了解是個大字典,裡面k有放很多的值,是個很大的集合。如果有一百萬人這麼操作 ,記憶體耗費是很大的。session有時間過期機制,但是這樣就有了攻擊方法,大批機器攻擊,就有可能記憶體資源耗盡。
**
其實通過域名 通路是可以通路到很多伺服器的,一般時刻,隻能通路同一台,就算同一個ip也會引導的不同機器上去的,假定是同一台機器。session預設情況下是和server服務相關,server1啟動了一個服務程序,單獨維護了記憶體裡的session,server2也是單獨維護自己程序裡的session。
第一次通路server1,但是後來dns變了,第二次通路server2去了,這時候就會有一種現象,用着用着就讓你重新登入
**
dns解析是udp53端口,,解析回來的資料會在本地緩存一段時間,就要看背景的排程了,或者後面session共享存儲
session是當你和伺服器建立會話的時候,由伺服器單獨為你生成一次會話,這次會話會單獨為你配置設定一個session,這個session至少有一個鍵值對,鍵就是id,值就是sessionid,這個sessionid會發給浏覽器端,浏覽器隻要不清除不過期不關閉浏覽器,這個sessionid就會随着下一次請求送出給伺服器,伺服器通過查表,判斷這個人是否聯系過。
但是浏覽器端可以關閉session,session時效,大多數伺服器端session過期也需要10分鐘左右,在這個10分鐘其實等着你去連結的,過了這個時間,伺服器就把sessionid清理掉了,再連接配接也不認識你。
**
作為程式員來講,session不是越多越好,對每個客戶建立session,對記憶體消耗很大,session跨節點也很難。s1
和s2各維護着session,用戶端1第一次通路s1,但是後來排程到s2了,就導緻重新登入。
以前很多購物車的實作都是session實作的,把商品id數量都放在裡面,結果你準備付賬,把你引導到s2了,購物車就沒了這是非常讨厭的 **
還有就是,購物車放滿了,出去吃個飯,伺服器端session過期了,替你清除了。
我們應該定期的給session資料做一次持久化
session是比較消耗記憶體,尤其是把購物車放到session裡,消耗更大。session是解決了無狀态,但是如果把使用者相關資料放到session上,會帶來非常大問題,1.記憶體耗盡,2.session丢失 的問題,如果程序崩了,這個session也就沒了
是以以前使用者登入了,定期給它持久化一次,不登入,沒法持久化,隻能放在cookie裡,現在浏覽器一關js和cookie,基本上沒有網站可以通路。
session的采取清除是LRU最近最少使用,就清除了
對于動态網頁技術來講 ,更需要session和cookie這樣的機制,當浏覽器第一次通路網站的時候,通過response會寫回去一個sessionid這樣的cookie,浏覽器會暫存這個cookie,使用者在連續對伺服器發送請求的時候,每一次請求都會将cookie帶回來,cookie裡有sessionid就繼續帶回來,伺服器端将通過帶回來的sessionid,對sessionid進行檢查,如果在自己的session集合中,發現了有sessionid,是這個id,表示确實是上次通訊的。
如果在現在的session集合裡沒找到sessionid,就給使用者重新發一個sessionid,session在伺服器端是比較耗費資源的。浏覽器有些關閉或者關閉标簽頁也相當于關閉浏覽器,sessionid就清除了
和伺服器tcp連結通訊的時候,tcp這個連結有可能斷掉,是以不帶sessionid根本不知道你是誰
**大網站後面都是叢集,為了讓使用者通路任何伺服器都有一樣的session,讓兩台的session保持一緻,但是比較浪費,資料充分,好處是可以備援。
**
還有一種,session放在redis裡,以前放memacached比較多,統一管理
開發必須了解session,要看怎麼放才是安全的,這是傳統的方式用session和cookie解決無狀态的問題
看看不用session的方案,session相當于把壓力給了伺服器端,伺服器需要維護一個資料結果,裡面把所有sessionid和其他值維護起來。
但是如果讓浏覽器來管,我們不可信,加一種算法,隻要你改資料就發現的了,比如保險的用https,ssl證書加密,安全性就比較高,它是非對稱加密,本來就比對稱加密難破解。
對稱加密,就是rar,zip有時候加個密,1234,别人也用1234解開,這就是對稱加密,同一個密鑰。
非對稱加密,有公鑰私鑰,公鑰.pub,私鑰是不帶pub,别人用你的公鑰加密,你用私鑰去解開。非對稱是比較難解開的。
單項散列值加密MD5,加了密解不回來了
**這裡也需要一種加密算法,不用session了,直接将資訊發往伺服器端,伺服器端帶過來就認為可以 了,類似cookie,但是原始的cookie是明文的,而且改了也不知道,是以需要一種防篡改機制,利用這種機制,防止别人篡改,一旦别人修改一個位元組或者一個位,這裡就能驗證出來,進而不相信你。
**
session和cookie用來确認身份,實際上就是用sessionid來讓無狀态變成有狀态。我們可以想辦法替換這個sessionid,将這個id有一個id發給用戶端,但是一定要确定,發送給用戶端的東西不得修改,修改就出問題 了。
我們就要使用某種方法對資料進行簽名,但凡修改了一個位,在伺服器用密鑰重新驗算一遍就知道改過了。簽名算法必須難破解,密鑰足夠的強
這就是密鑰
也有缺點,就是将資料送出到伺服器後,伺服器端就需要去解密驗證,就有加密和解密的過程,浪費了伺服器cpu計算時間。但是解決了session不同步,消耗記憶體的事情,這種方案非常節約計算機記憶體資源。
這個是自己玩的,浏覽器不認識,就要想辦法自己清除它,這就是JWT技術
JWT在做單點登入的身份驗證的時候比較多,如果伺服器比較多,用JWT是比較好的方案,傳統的方式是session的方式,登入完了,在session裡加個值,然後可以解決session問題,伺服器多起來,就非常複雜了。大的網站,不同頻道其實通路的是不同伺服器,怎麼知道你的session再另外的伺服器上有,就做起來很難,這時候就往往需要用到單點登入,在一個上面登入過,在其他伺服器上隻需要做驗證就可以了,比如JWT技術就可以搞定
JWT(json web token)token令牌,你的身份是誰就交出token,用json來傳輸資料是比較好的方案,要安裝一個庫,PyJWT
jwt是一個開源的工業标準
把右邊的資料編碼成左邊的樣子
它是把資料變成三部分,對應左邊三部分,第一部分header密文頭
最左邊是base64
這裡是資料,負載
這個頭宣傳是jwt,用什麼加密方式
這一部分是簽名
簽名部分
中間部分是資料,負載,要傳的資料
幾乎所有的語言都支援
安裝很簡單,安裝完了就這麼用
寫一個測試檔案
**基本用法,導入庫,雖然庫名字叫pyjwt,但是導入還是JWT,
**
jwt做編碼,對負載進行編碼,使用什麼密碼,采用什麼算法
得到的結果可以列印。用點号分成三段
,每一段對應不同的東西,第一段header,第二段payload,第三段signature簽名。
用戶端沒有辦法解密,除非知道密碼是什麼,浏覽器是不能看到這個密碼的
這裡就是解開了
跑一下
密碼錯誤直接告訴你簽名無效,這就叫篡改,篡改一位都不行
這裡就等于修改了加密以後的值,告訴頭資訊錯誤,因為每一部分都會驗證
首先把jwt分成三部分,header,payload負載,signature簽名
用base64解開一下
就是header部分,告訴jwt的類型,和算法 HS256
說明這裡面每部分都是base64編碼的
檢視payload這一塊
檢視singature,就報錯,報的錯是更新檔不對
base64發現缺了最多補兩個==等号,或者補一個,或者不補,就這三種情況,最笨的方法就這麼寫
這兩個可能正好有不合适,也需要補等号
*準備寫一個函數,bytes要加等号,base64編碼完之後,長度一定要湊齊,湊齊了是4的倍數。
首先把長度拿到,和4取模,告訴我們餘下的,就傳回b’='4-餘數,餘幾個減掉才能補
現在就一點問題都沒有
這就是簽名,簽完之後是二進制的
encode編碼過程,這裡是負載
看一些怎麼給我們處理的
這個負載先進來payload是個字典
key 密碼
algorithm算法
header頭都是預設值
将payload給json化了
這樣就拿到了一個json payload,拿到key和algorithm算法交給父類的encode,這一步完成了字典到json的轉換
然後再進行進一步的轉換,這裡拿到的是json payload
頭部就湊齊了
将這個頭校驗之後放在這裡,現在有了json payload和json 頭
用base64編碼,将json頭也就是字元串,将字元串程序base64編碼,将payload,進行json字元串編碼,在segments出現了兩個元素了。
一個是頭base64編碼,一個是payloadjson做了base64編碼
将前面兩個值直接用.點号連結
就是前面兩個部分
現在要做簽名,你的算法,和payload,都是signing_Input資料
傳進來一個算法後,就找到這個算法,用 這個算法将key密碼拿到,然後用算法預處理下key
然後通過簽名算法,将input資料和key開始簽名了
可以了解這句話意思,雖然是簽名,其實就是用你提供的key在做加密,加密的時候得到一個簽名。
如果這個簽名不出錯
就是把這個前面依然base64編碼了一下,編碼之後加到segments的尾部去了
最後輸出給你的是,将這三段base64,header,payload,signature簽名,用點号連結就傳回給你
我們要自己去寫該怎麼寫,現在第一部分值和第二部分值都有,也就是這兩個分别要json,用base64編一下即可,編完之後拿到的值就可以簽名了
先注釋掉
将第一段和第二段截取出來
jwt是将這個拼在一起得到它
導入看看預設的是什麼
從jwt下面,找算法函數】
這是一個kv集合,正好有key,傳回字典給我們
這裡預處理了key
現在得到一個算法,get_defaul得到一個字典,問字典有沒有這個key,有這個key,有就拿到算法了,也得到了newkey
現在用alg.sign簽名,簽名就是消息,是之前的sign_input,第二個是newkwey,處理過的 key,然後就把signature拿到了
做一下base64,encode
**解密的過程下面就有,解密的過程其實是一個反過來的過程,把值拿進來,斷開很多部分 **
這裡有一個校驗簽名的過程,首先要想辦法将你送出的資料斷開,如果不斷開,它也不知道什麼header,也不知道什麼是payload,雖然算法正确,因為key是在伺服器端驗證
隻要payload和header發生改變,算出來 的簽名一定不一樣
JWT三部分,修改任何一個,隻要重新算一遍,一定不會得到同一個簽名
這個payload資料現在是不加密的,是以使用的時候要注意,JWT并沒有解決加密的問題,也是将payload是用明文發送的,隻不過需要base64轉一下,并沒有加密,唯一加密的是簽名。三部分任何部分進行修改,都驗證失敗,是以叫防篡改。不是對資料進行加密。
密碼很重要需要管理好
jwt原理
base64隻是做了一個編碼,直接拿編碼解開,其實就發現這個東西就是明文傳輸的,是以它是防篡改的,大多數資料簽名都是來做防篡改的,簽名這種技術一般是防篡改,不允許你修改,但凡你修改了就丢棄,這個不可信。
驗算算法就是再算一遍看看是否一緻,不一緻就是驗算失敗
不要把敏感資料放到jwt,jwt是明文傳輸
jwt最常使用場景就是單點登入的問題,一旦使用者成功就會給使用者發jwt,使用者下一次請求的時候,就會像cookie一樣把jwt帶上,伺服器就檢驗jwt,檢驗合格就是身份确認,跟sessionid的确認方式一樣,隻不過在資料結構裡并沒有這樣的東西。
他把userid通過jwt帶過來,用算法解開,發現沒篡改過,這個userid就確定是上一個人,還要把這個userid到資料庫裡驗證一下,有沒有這個userid,有了才确認。
這個資料可以在很多地方使用,甚至跨域通路,比如搜狐到新浪,自己的伺服器做單點登入是可以認的。還可以通過公鑰私鑰確定請求消息發送者都是可信的‘
jwt使用了一些算法将我們發送給用戶端 的資訊做了簽名,這個簽名是防篡改的,并不對資料做任何的加密處理,也就是在浏覽器端通過base64解碼看到資料原文,不是做資料加密的,不要把敏感資訊放裡面