wtforms 使用
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 使用的更多相关文章
- flask-admin章节五:wtforms FormField超级炫酷使用
1. 概述 查看wtforms代码树fields目录的core.py,会发现在文件开头有这样的语句: __all__ = ( 'BooleanField', 'DecimalField', 'Date ...
- flask-admin章节二:wtforms的使用以及在数据库场景中使用QuerySelectField代替SelectField
概述 flask admin可以支持自定义视图,对于涉及到比较复杂的视图可以选择继承flask_admin.BaseView来定义自己期待的结构. 自定义的视图的每个函数可以使用flask_admin ...
- wtforms快速使用和源码分析(基于flask)
wtforms 和django的form组件大同小异,下面给出一个应用举例以便快速查询. 开始使用 from flask import Flask, render_template, request, ...
- 85、flask之wtforms
本篇导航: wtforms组件的使用 自定义From组件 一.wtforms组件的使用 1.flask中的wtforms WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进 ...
- flask WTForms源码分析及自定义WTForms
首先我们来创建一个From类 from wtforms.form import Form from wtforms import StringField from wtforms.validators ...
- 【Flask】 结合wtforms的文件上传表单
表单中的文件上传 基本的表单渲染,表单类设置等等就不多说了,参看另一个文章即可.但是那篇文章里没有提到对于FileField,也就是上传文件的表单字段是如何处理,后端又是如何实现接受上传过来的文件的. ...
- 使用 WTForms 进行表单验证的例子
#使用 WTForms 进行表单验证的例子 from wtforms import Form from wtforms import BooleanField from wtforms import ...
- Flask信号和wtforms
一.信号 1.1.所有内置信号 request_started = _signals.signal('request-started') # 请求到来前执行 request_finished = _s ...
- flask wtforms组件详解
一.简介 在flask内部并没有提供全面的表单验证,所以当我们不借助第三方插件来处理时候代码会显得混乱,而官方推荐的一个表单验证插件就是wtforms.wtfroms是一个支持多种web框架的form ...
随机推荐
- BZOJ1070 [SCOI2007]修车
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- HTLM4与HTML5的区别
准确的说应该是HTML4与HTML5的区别 主要区别: 1.doctype头的改变 2.html5中多出了很多标签和属性 还有一个要注意的是,我们通常说html5时会自动关联上css3,其实我理解的, ...
- Linux Network Related Drive
catalog . 通过套接字通信 . 网络实现的分层模型 . 网络命名空间 . 套接字缓冲区 . 网络访问层 . 网络层 . 传输层 . 应用层 . 内核内部的网络通信 1. 通过套接字通信 Lin ...
- [JavaWeb 用MyEclipse分别创建最简单的JSP程序和Servlet程序]
最近看了子柳的<淘宝技术这十年>,其中讲到因为负载和连接池问题,淘宝当年迫不得已从SUN请来一对工程师从LAMP架构转到Java+Oracle.作为一个PHP为“母语”的程序仔,真是感到压 ...
- CF 363B One Bomb(枚举)
题目链接: 传送门 One Bomb time limit per test:1 second memory limit per test:256 megabytes Description ...
- 软件产品案例分析--K米
软件产品案例分析--K米 第一部分 调研,评测 评测 个人第一次上手体验 使用的第一款点歌软件,以为就是个遥控而已,使用后发现功能还挺多,能点挺久.觉得很方便,不用挤成一堆点歌了.K米的脸蛋(UI)好 ...
- java常用集合详解 contains
java集合是对常用数据集合的封装,差不多就是数组吧,验证某个元素是否在数据集合里,最原始的方法是,用个循环,"某个元素"与数据集合中的每个元素逐个进行比较. java 对常用的一 ...
- PHP 数据库抽象层pdo
PDO是PHP数据对象(PHP Data Object)的缩写. pdo就是一个"数据库访问抽象层",作用是统一各种数据库的访问接口,能够轻松地在不同数据库之间进行切换,使得数据库 ...
- 在Nginx中部署基于IP的虚拟主机
一.虚拟主机概念 虚拟主机是在网络服务器上划分出一定的磁盘空间供用户放置站点.应用组件等,提供必要的站点功能.数据存放和传输功能.所谓虚拟主机,也叫"网站空间", 就是把一台运行在 ...
- redis auth php操作
<?php//Connecting to Redis server on localhost$redis = new Redis();$redis->connect('192.168.33 ...