概述
flask admin可以支持自定義視圖,對於涉及到比較復雜的視圖可以選擇繼承flask_admin.BaseView來定義自己期待的結構。
自定義的視圖的每個函數可以使用flask_admin.expose 語法糖來裝飾,從而可以定義自己期待接收的HTTP方法和對外的URL。
flask admin的良好封裝,使得自定義視圖非常的方便。
自定義視圖中少不了涉及各種表單操作,對於不是很習慣寫前端的朋友來說肯定壓力比較大。不過,懶人自有懶的辦法,可以選擇
wtforms package提供的表單功能以及繼承flask admin提供的模板很輕松就實現了產生表單頁面的功能。
並且flask admin的官網上是極力推薦繼承或者直接使用flask admin提供的模板。這樣,一個可以保持自定義視圖和
自己使用flask admin的sqla.ModelView視圖樣式保持一直,另外就是可以復用現成的東西釋放勞動力。
對於想要繼承flask admin的模板,可以自己看下flask admin具體渲染相關的邏輯就一目了然了,還是蠻直觀的。
對於不太想看源代碼的,可以理解為flask admin package目錄下的templates/bootstrap3/admin(具體是bootstrap3還是bootstrap2需要依據自己的需求)目錄下的模板都是可繼承的,
具體想繼承哪個看自己的需求。
如何使用wtforms
使用wtforms還是挺簡單的,直接繼承form.Form類就可以了
下面用一個例子介紹下
from wtforms import form, fields, validators, widgets from wtforms.ext.sqlalchemy.fields import QuerySelectField class MyForm(form.Form): args = fields.TextField(label=u'腳本參數') timeout = fields.IntegerField(label=u'超時時間', default=5)
以上定義了一個表單,有兩個元素,args和timeout,不過在頁面具體顯示時並沒有看到args和timeout。取而代之的是腳本參數和超時時間。
這是因為指定了label,這樣表單對應元素顯示就顯示label的值。
具體在flask admin application中想要把對應的頁面渲染出來,只需要用以下語句就可以了:
@expose('/<your_url>', methods = ['GET', 'POST']) def index(self): form = MyForm(request.form) if request.method == 'POST': if helpers.validate_form_on_submit(from): # do you logical return self.render('admin/file/form.html', form = form)
以上只是一個很簡潔的相關代碼,還是很簡潔的。admin/file/form.html是直接使用flask admin提供的模板,直接使用就可以了。
使用上面簡短幾行代碼就可以渲染出一個完整的表單來。對於簡單的應用場景,使用以上所講的就已經能夠完全滿足需求了。
不過,很多時候表單需要有下拉列表框,需要從數據庫中查詢數據來做具體的選擇。這樣的話,就需要涉及數據庫,涉及到多選列表框
flask admin多選列表框元素的使用也是蠻簡單的
choices = [('line', u'線形圖'), ('pie', u'餅狀圖'), ('column', u'直方圖'), ('bar', u'條形圖')] chart_type = fields.SelectField(label=u'類型', choices=choices)
也像上面定義的表單的args參數和timeout參數一樣,使用SelectField還是蠻簡單的。
wtforms 支持從數據庫中獲取數據
fields.SelectField可供使用的數據來源不僅可以是預定義的,也可以是從數據庫中查詢。
tasks = [(r.task_name, r.task_name) for r in db.session.query(Task).all()] task = fields.SelectField(label=u'發布任務', validators = [validators.required()], choices = tasks)
這樣就可以很方便的從數據庫中查詢到所有的記錄,並作為下拉列表框中的選項供使用者選擇。
使用SelectField存在的問題
不過嚴格來說,上述的場景並不是很適合用SelectField。因為在使用過程中會發現即使Task中的數據一直在更新而下拉列表框中的記錄永遠不變。
主要原因是task是表單類中的一個靜態成員,定義之后就保持不變。因此,即使Task表中的數據一直在變,但是tasks的結果是已經固定的。
使用QuerySelectField
解決的辦法還是有的,就是使用QuerySelectField,QuerySelectField並不在wtforms.fields文件中,所以導致我們我們並不知道它的存在。而且wtforms的官網也推薦我們
用SelectField支持從數據庫中獲取記錄,導致我們誤以為可以那么使用,我忽略了QuerySelectField。
QuerySelectField的使用
from wtforms.ext.sqlalchemy.fields import QuerySelectField class MyForm(form.Form): def query_factory(): return [r.name for r in db.session.query(Script).all()] def get_pk(obj): return obj name = QuerySelectField(label=u'腳本名', validators=[validators.required()], query_factory=query_factory, get_pk=get_pk)
QuerySelectField使用起來也是蠻簡單的,不過需要提供兩個函數,query_factory和get_pk這兩個函數。上例中的兩個函數是根據我自身使用的場景來
使用的,name是Script表的主鍵。所以,上例中能夠動態獲取Script表中的主鍵內容。下拉列表框的內容跟着Script表的數據變化在變化。剛好符合我們的需求。
結論
flask admin還是蠻強大的,越是到后面會發現很多意想不到的東西。要堅持不斷學習,不要妥協!