對Python flask框架圖片分享網站的總結
能力
- 瞭解的部分:
flask框架
application │ manage.py <-指令碼資料 │ runserver.py <-啟動伺服器 │ └─application <-web目錄 │ app.conf<-配置檔案 │ models.py <-資料模型 │ views.py <-檢視 │ __init__.py <-模組匯出檔案 │ ├─static <-靜態檔案 └─templates <-頁面模板 base.html index.html login.html
安裝模組:flask,Flask-SQLAlchemy,Flask-MySQLdb,Flask-Login,Flask-Script,nginx,gunicorn,jinjia2模板
基礎理解:
物件關係對映(Object-Relational Mapping):ORM
資料模型:sql-alchemy把model的資料模型和資料庫欄位對應起來
外來鍵(ForeignKey)始終定義在多的一方.如果relationship定義在多的一方,那就是多對一
- 深入瞭解的內容
jinjia模板繼承報錯(新增jinjia環境):app.jinja_env.add_extension('jinja2.ext.loopcontrols')
模板優勢:程式碼複用、巢狀
內部變數傳送:
request物件 method:當前請求方法(POST,GET等) url:當前連結地址 path:當前連結的路徑 environ:潛在的WSGI環境 headers:傳入的請求頭作為字典類物件 data:包含傳入的請求資料作為 args:請求連結中的引數(GET引數),解析後 form:form提交中的引數,解析後 values:args和forms的集合 json:json格式的body資料,解析後 cookies:cookie讀取
response物件 response = make_response(render_template(index.html)) 方法 status:響應狀態 headers:響應頭,設定http欄位 set_coockie:設定一個cookie
網頁渲染引擎:在Flask中我們把這一工作叫做渲染模板,其中我們準備好的網頁叫做模板,渲染工作交給一個叫做jinja2的模板引擎就好了,具體使用方法是呼叫函式render_template('檔名')。
我們所要渲染的所有模板都需要放在templates資料夾下,所以我們需要新建一個templates資料夾並將我們準備好的HTML檔案放進去,在這裡我們把它叫做test.html
到了這裡關於HTML的準備工作就完成了,接下來就是使用flask渲染模板
我們在與templates同一目錄下新建一個main.py檔案,寫下如下程式碼即可
from flask import Flask,render_template app = Flask(__name__) @app.route('/test') def test(): return render_template('test.html') if __name__ == '__main__': app.run()
可以看到我們例項化了一個Flask物件併為它定義了一個路由,當訪問地址為/test時使用render_template渲染模板test.html
- 橫向發展如何舉一反三
做完專案之後,思考spring框架的整體結構怎麼樣?spring框架都用了哪些技術,其他框架怎麼渲染,內部變數怎麼傳的
潛力
- 如何解決問題
發現使用jinjia2的時候會報錯,說明配置裡面沒有加jinjia2的使用環境,(----------------->舉一反三) - 怎麼舉一反三
讓我想起了以前的XXX框架也是出現了類似問題,我是如何解決的 - 如何優化專案
如何優化這個專案:
前端程式碼儘可能了壓縮減少頻寬
1. Web伺服器開啟Gzip壓縮
在HTTP協議中允許客戶端可以選擇從伺服器上下載壓縮的內容,Gzip就是其中一種支援的格式。
2. JavaScript程式碼壓縮
JavaScript壓縮的原理一般是去掉多餘的空格和回車、替換長變數名、簡化一些程式碼寫法等。
3. CSS程式碼壓縮
CSS程式碼壓縮原理和JavaScript程式碼壓縮的原理類似,也是去掉不必要的空格回車註釋等,並同時優化合並一些CSS規則定義,讓規則更簡潔。
4. HTML程式碼壓縮
壓縮HTML程式碼的爭議很大,反對的一方覺得壓縮的作用不大,不像壓縮JavaScript和CSS程式碼,壓縮HTML程式碼僅僅是去掉空格回車註釋等無關字元,並不會簡化HTML程式碼本身,所以覺得在伺服器開啟Gzip就足夠了。
5. 圖片資源壓縮
除了程式碼的壓縮外,網頁中使用最多的資原始檔就是圖片,在一般的網站中,圖片資源佔有的比重還是挺大的。圖片壓縮工具主要是線上工具和本地應用程式,還沒有好一點的編輯器外掛可用。好在一般專案中,圖片的變化並不是很大,所以圖片的自動化壓縮工具的需求並不是很迫切。
降低併發:
【使用快取】
使用cach-control或expires這類強快取時,快取不過期的情況下,不向伺服器傳送請求。當快取過期時,會使用last-modified或etag這類協商快取,向伺服器傳送請求,如果資源沒有變化,則伺服器返回304響應,瀏覽器繼續從本地快取載入資源;如果資源更新了,則伺服器將更新後的資源傳送到瀏覽器,並返回200響應
- 怎麼快速學習
完整閱讀一篇官方文件,從中學習框架等技術的整體框架,其他技術的學習都是一樣的。
分析
網站
- 許可權管理
1. 驗證欄位與密碼的儲存
許可權管理的基礎就是驗證欄位(使用者名稱or郵箱...)以及密碼, 所以首先需要考慮驗證欄位和密碼的儲存。(這裡使用flask-sqlalchemy作為ORM)
2. 使用者許可權與角色的設定
我一般將使用者許可權設定為16進位制的值, 而使用者角色則是使用者許可權(16進位制的值)的異或(|)運算,
那麼可設定如下角色, 並建立和User的多對一關係
現在只需在User裡建立一個指向使用者角色的外來鍵即可
flask許可權在具體場景中的應用
應用在具體場景, 使用相關擴充套件就不可避免了
1. 處理登入(flask-login)
對於flask登入,使用flask-login是較為簡單的辦法, 但是個人感覺
flask-login
不是很靈活(下面的擴充套件也是, 畢竟擴充套件的目的是通用)。 這裡就不具體說明如何整合flask-login了,主要說如何使用flask-login使用者登入
使用flask-login提供的
login_user
,current_user
使用者登出
使用flask-login提供的
logout_user
2. 處理HTTPBasicAuth(flask-httpauth)
flask-httpauth 可以幫助我們處理一些基本的許可權管理, 同flask-login一樣, flask-httpauth 也提供了一個login_required裝飾器, 通過auth物件呼叫即可控制使用者名稱, 密碼的登入許可權控制。
token許可權管理
這裡比較複雜的地方就是token的許可權管理了, 因為此處沒有拓展可用(擴充套件是為了通用性, 但是token不是強制使用的), 都是自己踩坑弄出來的, 寫在部落格裡做一個紀錄。
什麼是token
token是使用者資訊(一般是使用者id, 具有唯一標識作用)的標識。對使用者id進行簽名加密(我一般使用itsdangerous模組),
為什麼需要token?
token 一般使用在API的場景中, 此時客戶端和伺服器端是分離的, 資料資訊通過API進行傳遞, 他人很容易就可以攔截API並獲取驗證頭部的authorization欄位, 從而獲取使用者名稱和密碼(一般是base64進行了加密, 但是很容易被破解), 這樣是極不安全的。 之所以需要驗證, 其實就是為了標識這個使用者是誰, 而id就是一個最好的標識, 所以通過使用者的使用者名稱和密碼請求token(這樣使用者名稱和密碼不會頻繁被髮送), 用獲取的token放在API頭部進行傳遞, 這樣即使被攔截, 也不會獲取使用者的敏感資訊(使用者名稱, 密碼), 即使token被他人使用, 也會因為token的壽命而使破壞性大大降低。
token的使用: 傳送token
token需放在Authorization頭部, 採用如下形式傳送:
token的使用: 解析token
依然採用itsdangerous模組, 這裡金鑰就很重要了, 只有與加密相同的金鑰才可以解析token。
基於token的許可權管理
這裡主要是區別普通使用者和管理員使用者, 因為有些特定的操作是隻有管理員可以進行的。
1.在User類裡新增管理員判斷函式
2.建立管理員許可權判斷裝飾器
然後就可以使用admin_required裝飾器進行許可權管理了, 這裡有個坑提一下就是flask-httpauth會自己新增Basic, 所以使用該擴充套件的地方就不必考慮token格式的問題了。
- 資料庫安全
salt給密碼加鹽然後再加密儲存到資料庫中
單點登入
驗證碼機制防止爆破
郵箱/簡訊驗證(使用者有一箇中間狀態)
User使用者介面 is_authenticated is_active is_anonymous get_id()
核心函式和屬性 login_user(user) logout_user() login_required current_user
演算法
解決思路和靈感來源
關注網站的上網時間節點,來提高廣告的點選率----->這時候可以舉一反三,提高對使用者性別的關注來提高廣告的點選率 |
後記
多執行緒技術:
Thread 是threading模組中最重要的類之一,可以使用它來建立執行緒。有兩種方式來建立執行緒:
一種是通過繼承Thread類,重寫它的run方法;
另一種是建立一個threading.Thread物件,在它的初始化函式(__init__)中將可呼叫物件作為引數傳入.
Thread模組是比較底層的模組,Threading模組是對Thread做了一些包裝的,可以更加方便的被使用。
併發技術:
redis,資料結構,非同步,容錯機制
redis處理高併發思路:
使用者在下訂單之前當然是先查詢到這個商品,在這個查詢的時候,將資料庫中商品的剩餘數量存到redis中;
伺服器在一瞬間接到成千上萬的下訂單請求,在控制層沒有直接處理請求資料,而是先根據redis中商品的剩餘數量來判斷,如果>0,就將請求放到請求佇列中,否則直接響應客戶端“賣完了”;
考慮到資料的一致性,佇列的容量就是商品的剩餘數量,佇列採用的是執行緒安全的佇列LinkedBlockingQueue(單臺伺服器),然後通過新的執行緒非同步處理這些請求,多臺伺服器的話,可以考慮使用訊息佇列MQ,單獨用一臺伺服器去處理訊息佇列中的請求;
客戶端傳送訂單請求之後,會收到響應,要麼是剩餘數量不足(賣完了),要麼是請求已經被放到佇列中,為下一步的輪詢訂單做準備;
如果響應狀態是賣完了,直接提示客戶,如果請求已經放入佇列中,就可以根據使用者id和商品id去輪詢訂單了;