涉及到的插件和包有Flask-WTF,WTForms。内容有表单的创建使用流程,一些最佳实践,还有在页面显示提示消息的简单方式,配合Flask内置的 flash()
。
Flask的requset对象包含了client端发送过来的所有请求,在request.form中就有POST方法提交过来的表单数据。直接使用这些数据可以搞定表单的操作,不过不方便,于是有了Flask-WTF这个插件,它将WTForms这个包嵌入Flask里,简化Flask下的使用。pip安装会把插件的以来也安装进来:
WTForms应该也同时被安装了。
跨站请求伪造(Cross-Site Request Forgery,CSRF) 保护
CSRF的原理不具体讲了,很简单,感兴趣直接网上搜即可。
Flask-WTF默认提供对CSRF的保护。应用里需要设置一个加密用的key,Flask-WTF利用这个key生成一个加密的记号来验证request带过来的表单数据。看看实例:
|
app=Flask(__name__)
app.config['SECRET_KEY']='www.ttlsa.com'
|
app.config
是应用保存配置的一个字典。可以直接在字典里增加配置。SECRET_KEY
这个配置变量被Flask和一些第三方插件使用,对不同的应用配置不同的值增加点可靠性。
另外,这个值最好放到环境变量里,直接写到代码里不太好。
表单类
使用Flask-WTF的时候,每一个表单都是类的形式,这个类需要继承自Form。这个类里定义一些代表表单各类域的对象,每个对象可以有多个验证器(validators)。验证器可以确保用户的输入是有效的。
原例子:
|
from flask.ext.wtf import Form
from wtforms import StringField,SubmitField
from wtforms.validators import Required
classNameForm(Form):
name=StringField('What is your name?',validators=[Required()])
submit=SubmitField('Submit')
|
表单中的域在类中都定义成类变量。上例中,NameForm
类里有文本域name
和提交按钮submit
两个。StringField
代表有type="text"
属性的<input>
元素。SubmitField
代表有type="submit"
属性的<input>
元素。构造器的第一个参数是后续渲染表单时候用到的标签(label
)。
下例是一个带有文本域和提交按钮的表单例子:
|
fromflask_wtf importForm
fromwtforms importStringField,BooleanField,PasswordField,SubmitField
fromwtforms.validators importDataRequired
classLoginForm(Form):
openid=StringField('openid',validators=[DataRequired()])
remember_me=BooleanField('remember_me',default=False)
password=PasswordField('password',validators=[DataRequired()])
submit=SubmitField('submit')
|
表单中的域在类中都定义成类变量。上例中,LoginForm
类里有字符串域openid,
复选框remember_me, 密码域password,提交按钮submit
。分别代表小面信息:
|
<input id="openid"name="openid"type="text"value="">
<input id="remember_me"name="remember_me"type="checkbox"value="y">
<input id="password"name="password"type="password"value="">
<input id="submit"name="submit"type="submit"value="submit">
|
构造器的第一个参数是后续渲染表单时候用到的标签(label
)。
在StringField
里的validators
参数定义了一些验证器,这些验证器会在用户提交数据前检查数据是否有效。Required
验证器确保提交的内容不能为空。
WTForms提供的各种HTML域:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
域类型 含义
StringField 文本
TextAreaField 多行文本
PasswordField 密码类文本
HiddenField 隐藏文本
DateField 接收给定格式的datetime.datevalue的文本
DateTimeField 接收给定格式的datetime.datetimevalue的文本T
IntegerField 接收整数的文本
DecimalField 接收decimal.Decimal类型值的文本
FloatField 接收浮点类型值的文本
BooleanField 选是否的复选框
RadioField 包含多个互斥选项的复选框
SelectField 下拉菜单
SelectMultipleField 可多选的下拉菜单
FileField 文件上传
SubmitField 提交
FormField 讲一个表单作为域放入另一个表单里
FieldList 一组给定类型的域
|
WTForms提供的各种验证器:
1
2
3
4
5
6
7
8
9
10
11
12
|
Validator Description
Email 邮箱格式
EqualTo 比较两个域的值,例如在要求输入两次密码的时候
IPAddress IPv4地址
Length 按字符串的长度验证
NumberRange 输入数字需在某范围内
Optional 允许不填,不填的时候就忽略其他验证器
Required 必填
Regexp 通过一个正则表达式验证
URL URL格式
AnyOf 属于一组可能值中的一个
NoneOf 不属于一组可能值中的任何一个
|
渲染表单
表单的各类域在模板中渲染时表现为可调用的对象。假设将一个NameForm
的实例name
作为参数传入模板。
|
<form method="POST">
{{form.name.label}}{{form.name()}}
{{form.submit()}}
</form>
|
这样渲染出来的页面不美观,可以尝试改进下,在调用里传入一些参数,这些参数都会被转化为这个域的属性。然后你可以用CSS自己搞定美化问题:
|
<form method="POST">
{{form.name.label}}{{form.name(id='my-text-field')}}
{{form.submit()}}
</form>
|
上述方式显然很累,之前加入了Bootstrap的支持,Flask-Bootstrap插件其实也对Flask-WTF创建的表单有高层接口的支持,可以用Bootstrap来修饰一下。然后表单的模板就可以简单写成:
|
{%import"bootstrap/wtf.html"aswtf%}
{{wtf.quick_form(form)}}
|
从其他模板import个函数进来之前提到过,wtf.quick_form
函数接受一个Flask-WTF的表单,然后用Bootstrap默认的样式渲染。
现在,首页index.html
已经改为:
|
{%extends"base.html"%}
{%import"bootstrap/wtf.html"aswtf%}
{%block title%}Flasky{%endblock%}
{%block page_content%}
<div class="page-header">
<h1>Hello,{%ifname%}{{name}}{%else%}Stranger{%endif%}!</h1>
</div>
{{wtf.quick_form(form)}}
{%endblock%}
|
这里还用了一个if else结构,如果传入了name
,就显示传入的值,否则就显示Stranger。
表单的各类域在模板中渲染时表现为可调用的对象。假设将一个LoginForm
的实例openid作为参数传入模板。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<form action=""method="post"name="login">
{{form.hidden_tag()}}
{{form.openid.label}}
{{form.openid(size=80)}}
{%forerror inform.openid.errors%}
<span style="color: red;">{{error}}</span>
{%endfor%}<br>
密码:
{{form.password}}
{%forerror inform.password.errors%}
<span style="color: red;">{{error}}</span>
{%endfor%}
{{form.remember_me}}Remeber Me</p>
提交:
{{form.submit(value='登录')}}
</form>
|
视图函数中的表单处理
修改hello.py,在index()
里处理表单数据。
|
@app.route('/',methods=['GET','POST'])
def index():
name=None
form=NameForm()
ifform.validate_on_submit():
name=form.name.data
form.name.data=''
returnrender_template('index.html',form=form,name=name)
|
可以注意到,在app.route
装饰器增加了methods
参数,这里是把index()
注册为GET和POST请求的处理者。如果不提供methods
这个参数,试图函数默认只处理GET请求。
这里对index()
增加视图函数对POST请求的支持是必须的,因为用户的提交操作使用POST请求更方便处理。使用GET请求来提交表单也可以,但是GET请求的数据都是附加在URL后面作为请求字符串,在浏览器的地址栏可以看到。由此,以及一些其他原因,表单的提交通常都是用POST请求完成的。
继续看改动后的代码,form.validate_on_submit()
这个方法,只在用户提交了数据并且数据通过验证器的检查之后,才返回True,其他时候都返回False。用这个方法判断是否对模板进行处理。
看下一般处理流程。用户第一次访问这个应用,使用的是GET请求,不带数据,form.validate_on_submit()
这个方法返回False,return就返回一个空白的表单,name
值是None。
用户提交了表单后,sercer收到携带数据的POST请求,form.validate_on_submit()
这个方法会启动之前设置的Required()
验证器,这里name不为空就通过验证,form.validate_on_submit()
返回True。然后提取出表单数据保存下来,把表单数据清空。再把name和表单传入render_template()
,重新渲染的模板就有了变化。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@app.route('/login',methods=['GET','POST'])
def login():
form=LoginForm()
print form.openid
print form.remember_me
print form.password
print form.submit
ifform.validate_on_submit():
flash('Login requested for OpenID="'+form.openid.data+'", remember_me='+str(form.remember_me.data)+' password: '
)
returnredirect('/index')
returnrender_template('login.html',title='Sign In',form=form)
|
相关推荐
而Flask-WTF-Polyglot则是Flask生态中的一个重要扩展,它极大地丰富了Flask在Web表单处理方面的功能。本文将详细探讨这个库的核心概念、使用方法以及它如何帮助开发者提高工作效率。 首先,Flask-WTF-Polyglot是...
Flask-WTF-FlexWidgets的特色在于其灵活性,它允许开发者自定义表单字段的渲染方式,可以创建复杂的表单布局,如使用Bootstrap等前端框架来美化表单。此外,它还支持动态表单,可以根据后端数据动态生成或修改表单...
7. **第三方扩展兼容**:Flask-SQLAlchemy与许多其他Flask扩展良好配合,如Flask-WTF用于表单处理,Flask-Restful用于API开发等,构建完整的Web解决方案。 在实际开发中,我们可以按照以下步骤使用Flask-SQLAlchemy...
6. **易于扩展**:通过插件系统,可以方便地添加各种功能,如SQLAlchemy用于数据库操作,Flask-WTF用于表单处理等。 三、Flask的一键部署 一键部署通常意味着开发者只需要执行一个命令或者进行简单的配置,就能将...
**PyPI官网下载Flask-WTF-0.10.0.tar.gz详解** 在Python的开发环境中,PyPI(Python Package Index)是最重要的资源库,它提供了大量的第三方库供开发者使用。`Flask-WTF`是PyPI上的一款非常实用的库,它是`Flask`...
《Python库Flask_app-1.0.1-py3-none-any.whl详解》 在IT行业中,Python作为一门简洁且...在实际开发中,结合其他Python库如`flask_login`(用户认证)、`flask_wtf`(表单处理)等,可以构建出功能强大的Web应用。
扩展通常以`Flask-XXX`的形式命名,例如`Flask-SQLAlchemy`用于SQLAlchemy支持,`Flask-WTF`用于表单处理。`flask_python_ldap`就是这样的一个扩展,提供对LDAP的支持。 5. **安装与使用**: 要在Python环境中安装...
Flask-Stupe是Flask的一个增强版,它包含了多个常用的Flask扩展,如Flask-SQLAlchemy(用于数据库操作)、Flask-WTF(用于表单处理)和Flask-Login(用于用户认证)。这些扩展都是Flask-Stupe的核心组成部分,它们...
Flask 本身并不会帮助我们处理表单,但是 Flask-WTF 扩展让我们在我们的 Flask 应用程序中使用流行的 WTForms 包。这个包使得定义表单和处理提交容易一些。 Flask-WTF 我们想要使用 Flask-WTF 做的第一件事情(在...
10. **扩展与插件**:Flask拥有丰富的生态,如Flask-WTF用于表单处理,Flask-Mail用于发送邮件,开发者可以通过这些扩展快速增强应用功能。 总的来说,Python基于Flask的管理系统源码是一个学习Flask框架和后端开发...
- **Flask-WTF**: 提供表单处理和验证功能。 - **Flask-SQLAlchemy**: 用于集成SQLAlchemy数据库 ORM。 - **Flask-Login**: 实现用户登录状态管理。 - **Flask-RESTful**: 支持RESTful API的构建。 - **Flask-...
6. **插件系统**:Flask拥有丰富的插件生态,如Flask-SQLAlchemy用于数据库操作,Flask-WTF进行表单处理,Flask-RESTful构建RESTful API等,这些扩展可以极大地扩展Flask的功能。 **Python库与Flask的关系** 在...
Flask的灵活性允许开发者根据需求选择不同的扩展,如Flask-SQLAlchemy用于数据库管理,Flask-Login进行用户认证,Flask-WTF处理表单数据等。通过这些扩展,Flask能够支持各种复杂的应用场景,从简单的个人博客系统到...
- **Flask扩展**:为了增强功能,Flask有众多第三方扩展,如Flask-SQLAlchemy(数据库管理)、Flask-WTF(表单处理)等。 - **配置扩展**:通过`app.config`,我们可以设置扩展的配置选项,使其与项目需求匹配。 ...
- Flask-WTF是Flask的一个扩展,它提供了表单验证的功能。 - **3.2 Configuration** - 配置Flask-WTF涉及到设置一些选项,比如密钥等。 - **3.3 User Login Form** - 介绍如何创建一个登录表单,并验证用户输入的...
Flask-WTF扩展提供了与WTForms集成,简化了表单处理。在用户登录时,可能会使用一个表单类来定义输入字段,然后在视图函数中接收并验证表单数据。 **八、错误处理与日志记录** 为了提供良好的用户体验,应用应能...
- 使用Flask-WTF扩展来处理表单数据。 - 需要先安装Flask-WTF: ```bash pip install Flask-WTF ``` - 创建表单类,并在视图函数中处理表单提交的数据。 #### 四、Flask案例示例 下面是一些Flask应用的例子...
5. **扩展功能**:Flask的生态系统中有大量扩展,如Flask-SQLAlchemy用于数据库操作,Flask-WTF进行表单处理,Flask-Login处理用户认证等。尽管"flask-sample-0.4a4"可能并未包含所有这些扩展,但了解它们的存在可以...
开发者可以利用其扩展性,添加如SQLAlchemy(ORM)、Flask-SQLAlchemy(Flask与SQLAlchemy的集成)、Flask-WTF(表单处理)等插件,以实现更复杂的功能。 2. **MySQL数据库**:作为数据存储的主要工具,MySQL用于...