fields.SelectField可供使用的數據來源不只能夠是預約義的,也能夠是從數據庫中查詢。sql
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存在的問題session
不過嚴格來講,上述的場景並非很適合用SelectField。由於在使用過程當中會發現即便Task中的數據一直在更新而下拉列表框中的記錄永遠不變。函數
主要緣由是task是表單類中的一個靜態成員,定義以後就保持不變。所以,即便Task表中的數據一直在變,可是tasks的結果是已經固定的。ui
使用QuerySelectFieldcode
解決的辦法仍是有的,就是使用QuerySelectField,QuerySelectField並不在wtforms.fields文件中,因此致使咱們咱們並不知道它的存在。並且wtforms的官網也推薦咱們orm
用SelectField支持從數據庫中獲取記錄,致使咱們誤覺得能夠那麼使用,我忽略了QuerySelectField。sqlalchemy
QuerySelectField的使用ip
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表的數據變化在變化。恰好符合咱們的需求。get