flask-admin章节二:wtforms的使用以及在数据库场景中使用QuerySelectField代替SelectField

摘要:
此外,强烈建议继承或直接使用flaskadmin在flaskadmin官网上提供的模板。wtforms支持从数据库中获取数据字段。SelectField不仅可以从预定义的数据源中使用,也可以从数据库中使用。使用SelectField时出现问题。严格来说,上述场景不适合使用SelectField。仍然有一种方法可以通过使用QuerySelectField来解决这个问题。QuerySelectField在wtforms Fields文件中不可用,因此我们不知道它的存在。此外,该平台的官方网站还建议我们使用SelectField从数据库中获取记录。结果,我们错误地认为我们可以这样使用它。我忽略了QuerySelectField。

概述

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还是蛮强大的,越是到后面会发现很多意想不到的东西。要坚持不断学习,不要妥协!

免责声明:文章转载自《flask-admin章节二:wtforms的使用以及在数据库场景中使用QuerySelectField代替SelectField》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇常用的 Python 标准库都有哪些?PCB产业链、材料、工艺流程详解(1)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

linux下导入导出MySQL数据库

一、导出:用mysqldump命令行命令格式mysqldump -u 用户名 -p 数据库名 > 数据库名.sql范例:mysqldump -u root -p abc > abc.sql(导出数据库abc到abc.sql文档)提示输入密码时,输入该数据库用户名的密码。 *************************************...

AttributeError: module 'DBBase' has no attribute 'DBBase'

AttributeError: module 'DBBase' has no attribute 'DBBase' pycharm不会将当前文件目录自动加入自己的sourse_path。右键make_directory as-->Sources Root将当前工作的文件夹加入source_path就可以了。 还有一点:models加一个点,表示同级目...

Oracle数据库的启动和关闭过程

一、Oracle数据库的完整启动过程是分步骤完成的,包含以下3个步骤 启动实例-->加载数据库-->打开数据库 因为Oracle数据库启动过程中不同的阶段可以对数据库进行不同的维护操作,对应我们不同的需求,所以就需不同的模式启动数据库。 1. Oracle启动需要经历四个状态:SHUTDOWN 、NOMOUNT 、MOUNT 、OPEN 2....

Oracle 12c 数据库中scott用户不存在的解决方法

-- 使用超级管理员登录CONN sys/change_on_install AS SYSDBA ;-- 创建c##scott用户CREATE USER c##scott IDENTIFIED BY tiger ;-- 为用户授权GRANT CONNECT,RESOURCE,UNLIMITED TABLESPACE TO c##scott CONTAINE...

C#中利用ODP实现瞬间导入百万级数据详解

.NET程序中可以通过ODP调用特性,对Oracle数据库进行操作,今天来讲一下数据批量插入的功能,所用技术不高不深,相信很多朋友都接触过,小弟班门弄斧了,呵呵。这篇文章是上篇文章的续集,因为上一次试验的征集结果没有突破4秒的方法,所以这次继续挑战与挖掘新方法,虽然是Oracle,但仍具有一定收藏意义。 这个试验是针对SQL SERVER数据库的,宿主环境...

MySQL导入、导出、数据库定时备份

  本篇使用的MySQL版本是5.7.30,注意不同版本之间可能会有差异。   一、导出操作   1、查找mysqldump命令位置 which mysqldump   2、mysqldump导出示例   用户名和密码分别是root和123456;导出远程库,使用-h+IP和-port+端口,如下所示。后面的命令默认导出本地库。 /usr/bin/mysq...