wtforms是一个表单模板库, 下面以修改密码表单为例简单说明其用法.
我们可以用python代码定义form的基本元素, 比如用户名/邮箱, 并给定各个元素的validation条件.

然后在render_template()方法中, 将python的form类传递给html模板. 在模板上, 需要有placeholder来接纳python传过来的form元素.

使用wtforms的好处是:
1. form验证可以使用python来做, 不必将验证代码放到javascript中.
2. 在python视图函数中, 可以很方便地获取表单元素, 比如使用form.username.data, 即可获取表单上的username值.
3. 可以简化html模板的设计. 采用Flask-Bootstrap 扩展或者使用一些jinja2 marco都能简化html代码.
4. 更重要的好处是, 将validation逻辑从表现层中解耦

下面仅讲解wtforms和bootstrap的结合使用, 而不涉及wtforms的基本用法.

bear-z写的bootstrap的macro
http://bear-z.com/python/render-bootstrap-3-forms-with-wtforms-and-jinja/

wtforms和bootstrap结合使用的详解
http://pythonthusiast.pythonblogs.com/230_pythonthusiast/archive/1315_flask_biography_tutorial_part_vi__adding_sign_up_form_using_bootstrap_3_and_flask-wtf.html

Flask-Bootstrap的简单用法
1. 安装Flask-Bootstrap后, 将Flask-Bootstrap的bootstrap模板目录放在我们自己的templates目录下, 即形成一个二级子目录.
2. 将flask的app做封装
    from flask_bootstrap import Bootstrap
    Bootstrap(app)
3. 定义python的一个WTF form类, 比如 MyForm
4. 在flask的view函数中, 将MyForm实例传到模板html中,  即render_template('MyForm.html',form=MyForm())
5. 在MyForm.html模板中, 引入flask_bootstrap的wtf macro文件, 最简单的方法是wtf.quick_form(), 即可将 MyForm python类定义的所有元素渲染到html上.  
  {% import "bootstrap/wtf.html" as wtf %}
  ....
    <div>         
        {{ wtf.quick_form(form, id="myform", form_type="horizontal", horizontal_columns=('sm', 2, 5)) }}
        <!-- 上面horizontal_columns()后两个参数是用来标示每一行的label和textbox的宽度 -->
    </div>

Flask-Bootstrap的quick_form()生成的html往往只适用于简单的排版, 所以比较适合做demo. 即使直接用wtf.form_field()来渲染每个元素, 也没有办法指定css class, 灵活度不高. 不过, 我们可提取出Flask-Bootstrap生成的html样式, 做为下一步美化的基础.

bear-z写的bootstrap的macro, 和Flask-Bootstrap相比, 灵活度高一些, 可以通过class_参数为每个元素指定css class.
{% import "bootstrap/bearz_wtf.html" as wtf2 %}
{{ wtf2.render_field(form.email, label_visible=false, placeholder='userID', type='email',class_='col-md-8') }}

涉及到表单提交, flask视图函数其实都是一个样子. 先看请求类型, 如是POST, 验证form上的数据, 验证通过则更新, 不通过则返回到原来的Form. 如请求是GET, 则表明是新的请求, 初始化一个新的Form, 并做html渲染.

下面是一个更新密码的示例.

##############################################
#flask view 模块
##############################################
@mod.route('/MyApp/updatePwd/', methods=['GET','POST'])
def udpatePwd():
    if request.method == 'POST':  # construct WTF form object based on request data
        form = UserPwdForm(request.form)
        if form.validate():       # WTForm validation OK
            user=User.getUser(form.EMPNO.data)
            aborted=False
            if user is None:
                aborted=True
                form.EMPNO.errors.append('This EmpNo does not exist.')
            if not aborted and not User.checkUserPwd(form.EMPNO.data, form.PWD.data):
                aborted=True    
                form.PWD.errors.append('Old password is not correct.')
            if aborted:
                return _navigateToUpdatePwd(form)  # return the page with error message
            else:  # all validation OK
                try:
                    User.updatePassword(form.EMPNO.data,form.NewPWD.data)
                    return _navigateSuccessfulPage()
                except Exception as e:
                    return _navigateErrorPage(logger=current_app.logger, exception=e)
        else:  # validation failed
            return _navigateToUpdatePwd(form)         
        
    else:  # GET request
        return _navigateToUpdatePwd(UserPwdForm())
 
 
def _navigateToUpdatePwd(form):
    return render_template("form_update_pwd.html",  
                            form=form,
                            )

def _navigateSuccessfulPage():
    return render_template("form_successful.html",  
                            )      
                   
                   
def _navigateErrorPage(logger, friendlyErrorMsg=None, exception=None):
    if exception:
        msg='%s'%exception
        tracebackInfo=traceback.format_exc()
        tracebackInfo=tracebackInfo.replace(chr(10), '<br>')
        tracebackInfo=tracebackInfo.replace(chr(13), '<br>')

if friendlyErrorMsg:
        msg=friendlyErrorMsg
        
    logger.error(msg)    
    if exception:
        logger.exception(exception)  
   
    #output the msg highlighted in danger  
    flash(msg, 'error')
    return render_template("form_error.html",  
                            tracebackInfo=tracebackInfo
                            )

##############################################                            
#flask form 模块
##############################################
from flask_wtf import Form
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, EqualTo, Length, InputRequired
from wtforms.fields.simple import PasswordField

class UserPwdForm(Form):
    
    EMPNO=StringField('Emp No',validators=[
        DataRequired('Please enter Emp No'),
        Length(min = 1, max = 20,message='length must between 1 and 20')
    ])
    
    PWD=PasswordField('Old password',validators=[
        DataRequired('Please enter old password'),
    ])    
        
    NewPWD=PasswordField('New password',validators=[
        DataRequired('Please enter new password'),
    ])    
    
    RptNewPWD=PasswordField('Confirm new password',validators=[
        DataRequired('Please confirm new password again'),
        EqualTo('NewPWD','Password must be match')
    ])        
        
    submit = SubmitField('Submit')

##############################################    
# html文件 form_update_pwd.html    
##############################################
{% if not is_xhr|default(false) %}{% extends "report_base.html" %}{% endif %}
{% import "bootstrap/wtf.html" as wtf %}
{% import "bootstrap/bearz_wtf.html" as wtf2 %}

{% block other_head_javascript %}
    <script src="/static/js/jquery.min.js"></script>
{% endblock %}

{% block content %}
 
      <h1>Update password</h1>
     
       <div>         
           {{ wtf.quick_form(form, id="FormUpdatePwd", form_type="horizontal", horizontal_columns=('sm', 2, 5)) }}
       </div>
 
        
{% endblock %}

##############################################
# html文件 form_successful.html
##############################################
{% if not is_xhr|default(false) %}{% extends "report_base.html" %}{% endif %}
{% import "bootstrap/wtf.html" as wtf %}
{% import "bootstrap/bearz_wtf.html" as wtf2 %}

{% block other_head_javascript %}
    <script src="/static/js/jquery.min.js"></script>
{% endblock %}

{% block content %}
 
<h1>Updated successfully.</h1>
        
{% endblock %}

理解session和cookie
http://lucindabfls.blog.163.com/blog/static/1247404702010326103548751/
http://hqhou.blog.163.com/blog/static/852039352013431033327/

wtforms 使用的更多相关文章

  1. flask-admin章节五:wtforms FormField超级炫酷使用

    1. 概述 查看wtforms代码树fields目录的core.py,会发现在文件开头有这样的语句: __all__ = ( 'BooleanField', 'DecimalField', 'Date ...

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

    概述 flask admin可以支持自定义视图,对于涉及到比较复杂的视图可以选择继承flask_admin.BaseView来定义自己期待的结构. 自定义的视图的每个函数可以使用flask_admin ...

  3. wtforms快速使用和源码分析(基于flask)

    wtforms 和django的form组件大同小异,下面给出一个应用举例以便快速查询. 开始使用 from flask import Flask, render_template, request, ...

  4. 85、flask之wtforms

    本篇导航: wtforms组件的使用 自定义From组件 一.wtforms组件的使用 1.flask中的wtforms WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进 ...

  5. flask WTForms源码分析及自定义WTForms

    首先我们来创建一个From类 from wtforms.form import Form from wtforms import StringField from wtforms.validators ...

  6. 【Flask】 结合wtforms的文件上传表单

    表单中的文件上传 基本的表单渲染,表单类设置等等就不多说了,参看另一个文章即可.但是那篇文章里没有提到对于FileField,也就是上传文件的表单字段是如何处理,后端又是如何实现接受上传过来的文件的. ...

  7. 使用 WTForms 进行表单验证的例子

    #使用 WTForms 进行表单验证的例子 from wtforms import Form from wtforms import BooleanField from wtforms import ...

  8. Flask信号和wtforms

    一.信号 1.1.所有内置信号 request_started = _signals.signal('request-started') # 请求到来前执行 request_finished = _s ...

  9. flask wtforms组件详解

    一.简介 在flask内部并没有提供全面的表单验证,所以当我们不借助第三方插件来处理时候代码会显得混乱,而官方推荐的一个表单验证插件就是wtforms.wtfroms是一个支持多种web框架的form ...

随机推荐

  1. Linux process authority、the security risks in running process with high authority

    catalog . Linux进程权限原理 . 最小权限原则 - 进程降权运行最佳实践 . 进程权限控制包含的攻防向量 . 进程高权限安全风险检查技术方案 1. Linux进程权限原理 我们知道,Li ...

  2. A.Kaw矩阵代数初步学习笔记 7. LU Decomposition

    “矩阵代数初步”(Introduction to MATRIX ALGEBRA)课程由Prof. A.K.Kaw(University of South Florida)设计并讲授. PDF格式学习笔 ...

  3. spring 初始化之后执行的方法

    Spring初始化完成后直接执行一个方法,初始化数据(解决方法并执行两次) 在做WEB项目时,经常在项目第一次启动时利用WEB容器的监听.Servlet加载初始化等切入点为数据库准备数据,这些初始化数 ...

  4. Beta版本——第五次冲刺博客

    我说的都队 031402304 陈燊 031402342 许玲玲 031402337 胡心颖 03140241 王婷婷 031402203 陈齐民 031402209 黄伟炜 031402233 郑扬 ...

  5. 高性能JavaScript(您值得一看)

    众所周知浏览器是使用单进程处理UI更新和JavaScript运行等多个任务的,而同一时间只能有一个任务被执行,如此说来,JavaScript运行了多长时间就意味着用户得等待浏览器响应需要花多久时间. ...

  6. SaltStack之Job管理和Runner(八)

    SaltStack之Job管理和Runner 配置文件/etc/salt/master cachedir: /var/cache/salt/master # cache路径 keep_jobs: 24 ...

  7. JavaScript中的变量及数据类型

    转自:http://blog.csdn.net/mygis2005/article/details/7375419 JavaScript是一种弱类型的语言,变量名.操作符和方法名都区分大小写. 1.变 ...

  8. C#中字符串的操作

    1.Replace(替换字符):public string Replace(char oldChar,char newChar);在对象中寻找oldChar,如果寻找到,就用newChar将oldCh ...

  9. tomcat的下载安装和配置以及和eclipse的配置

    一.Tomcat的下载安装环境变量配置 下载Tomcat 可以安装Tomcat了.下载好压缩包后,直接解压至某一目录下,目录中不能包含中文,上面安装JDK的时候也是.解压后如下所示: 将此文件夹拷贝到 ...

  10. 视频直播APP开发分析

    视频直播APP开发到目前为止都还是热门的一个行业,而且发展到现在直播的种类非常多,很多行业都打入了直播行业,再也不是单纯的人物直播这么单一了.视频直播APP开发行业就像是吃螃蟹,来的早的人不懂如何吃, ...