Flask專案筆記

2022-08-23 11:42:08 字數 2978 閱讀 9802

近期在搞乙個簡單的專案和庫存管理系統,用flask+gunicorn邊學邊做,有一些心得如下,和大家分享。老司機們別笑;)

1. gunicorn真好用

a)   flask自己的伺服器效能很差,動不動抽風,只適合拿來開發和除錯用。用gunicorn按(1 + 2 * ncpu)個worker啟動之後,在只有10+使用者量的系統裡再沒碰到效能問題,絲般順滑。

c)   使用gunicorn之後,更新程式也不用去kill process了。我現在的更新方法是自己電腦上的新版本**git push到**服務上,然後雲伺服器上git pull。記住gunicorn的daemon程序的pid,通過傳送hup訊號給gunicorn的daemon程序,它就會自動kill並boot新的worker程序。命令如下: 

$ kill –sighup

d)   我的gunicorn啟動命令: 

$ nohup gunicorn --workers=3 : -b host:port &

2. orm很方便

a)   儘管orm存在效能問題,不過可以通過自己定製sql語句優化。我在之前基於zabbix2.x版本資料庫做後台開發的專案中嘗試不用orm,寫了很多很多sql**。後來需求改了,重構的體驗太差了,非常地不靈活。現在老老實實先用orm做初步開發,非常的舒適。

b)   倒序查詢示例: 

db.session.query.order_by(db.desc(user.id)).all()

c)   參考,目前我所有的db.relationship都用了lazy引數。遇到過乙個小問題,比如我想知道user關聯的`proeject`表中有幾個專案,我直接len(u.projects)就出錯了。因為u.projects其實還是個query類。我暫時的fix方法是len(u.projects.all())。後續應該引入sqlalchemy中的func類裡的count作更加合適的改寫。

d)   merge好方便。前期開發偷懶用的sqlite,後來需要遷移資料到mysql,需要sqlalchemy做類似於「insert … on duplicate key update …」的功能(這裡還有乙個坑是把大文字寫入mysql時要把表的編碼設定成utf8mb4,utf8會報」只支援3個位元組」的異常)。

3. 修改flask-bootstrap預設採用的外國cdn源

預設flask會先找本地有沒有jquery和bootstrap的資源,沒有就載入cdn。我覺得cdn肯定比我的1m小水管快,那這cdn源的定製就是個問題了。

>>> cdns = bootstrap[『cdns』]

>>> cdns

>>> cdns['bootstrap']

>>> cdns['bootstrap'].primary

>>> cdns['bootstrap'].fallback

>>> cdns['bootstrap'].fallback.baseurl

''跟到這裡,我們如果把這個baseurl修改了,且static目錄下沒有已經存放的bootstrap的css和js資源時,網頁會載入我們修改後的cdn url。

當然我們可以直接修改flask-bootstrap的原始碼來更改cdn,不過這樣我們要把**部署到其他環境時就不能pip install -r requirements.txt就能執行了。

關鍵**如下:

from flask_bootstrap import bootstrap, webcdn

# ...省略**...

bootstrap_cdn = webcdn(bootstrap_url)

# ...省略**...

4. flask-wtf的一些問題

偷懶起見,我直接採用wtf.quick_form()巨集來渲染頁面表單。但是我有乙個需求,類似於「修改資料」的頁面,表單給使用者時,輸入項帶上資料庫中原先有的資料,以避免使用者還需要再填寫一遍。一開始我用的方法是在form例項的field具體屬性上,我修改它的`default`屬性,類似這樣:

class form(flaskform):

name = stringfield('what\'s your name?')

submit = submitfield('submit')

def view_func():

if requet.method == 'post':

pass

else: # request.method == 'get'

form = form()

name_old = get_name_from_db() # 從資料庫拿到了名字

form.name.default = name_old

return render_template('form.html', form=form)

然後我發現渲染出來的頁面並沒有帶上name_old。根據stack overflow上相關的問題,根據不同的wtform版本,這個方法有的管用有的不管用。

目前wtforms針對預設填入值的功能,正確的實現方法是在建立表單物件時傳入乙個data字典,把上面**改成這樣:

class form(flaskform):

name = stringfield('what\'s your name?')

submit = submitfield('submit')

def view_func():

if requet.method == 'post':

pass

else: # request.method == 'get'

name_old = get_name_from_db() # 從資料庫拿到了名字

form = form(data=)

return render_template('form.html', form=form)

flask開發專案筆記

開啟cmd視窗 5.7.18mysql安裝路徑 一 安裝虛擬環境 1 安裝虛擬環境pip install virtualenv 2 建立虛擬環境virtualenv flask env 3 cd到 flask env scripts activate啟用 啟用後目錄前多了乙個 flask env 表...

Flask專案筆記 2

密碼加密時,採用的是sha256加密,但不能直接對密碼進行加密,因為密碼相同的話,其加密後的值就相同,有暴露的風險,所以在給密碼加密時還需在讀取到的密碼中加乙個鹽值 salt 即一串隨機的字串 然後在對其進行加密 property裝飾器 接收儲存完資料,需要儲存登陸狀態到session中 儲存登入狀...

Flask專案結構

專案排版 首先建立專案目錄 mkdir flask tutorial cd flask tutorial接下來按照前一篇講過的安裝flask步驟進行安裝,並新建乙個虛擬環境。flask應用可以簡單到使用乙個單檔案,例如hello.py from flask import flask defhello...