文章内容

2018/8/4 16:57:27,作 者: 黄兵

wtforms selectfield支持从数据库中获取数据


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表的数据变化在变化。刚好符合我们的需求。


参考资料:wtforms的使用以及在数据库场景中使用QuerySelectField代替SelectField

分享到:

发表评论

评论列表