chapter4 - Web表单
4.1 跨站请求伪造保护
默认情况下,Flask-WTF可
本书使用的是Flask-WTf扩展来处理Web表单,它是把一个独立的WTForms集成了在Flask程序中。可以使用pip安装:(venv) $ pip install flask-wtf 4.1 跨站请求伪造保护 默认情况下,Flask-WTF可以保护所有表单免受跨站请求伪造(Cross-Site Request Forgery, CSRF)的攻击。为了实现这个防护,Flask-WTf需要在程序中设置一个密钥,然后再使用这个密钥生成加密令牌,再用令牌验证请求中表单数据的真伪。设置密钥的方法如下: hello.py
为了安全起见,密钥是不应该硬编码到程序中的,而是要保存到环境变量中。到第7章会介绍 4.2 表单类 使用Flask-WTF时,每个web表单都继续自Form类。这个类中包含了常用HTML表单中的各种字段,还为这些字段设置了一些验证函数可供使用,用于验证表单的输入数据。 如下为一个简单的weg表单,包含了一个文本字段和一个提交按钮: hello.py
name是一个文本字段,submit是一个提交按钮,分别相当于HTML中的:
name使用的StringField方法的第一个参数是显示在页面中的提示信息,第二个参数是一个表单验证项,用validators=[]方法实现,该方法接收一个列表,可在列表中放置多个验证函数。 以下是WTForms支持的HTML标准字段: 字段类型说明StringField文本字段TextAreaField多行文本字段PasswordField密码文本字段HiddenField隐藏文本字段DateField文本字段,值为datetime.date格式DateTimeField文本字段,值为datetime.datetime格式IntegerField文本字段,值为整数DecimalField文本字段,值为decimal.DecimalFloatField文本字段,值为浮点数BooleanField复选框,值为True或FalseRadioField一组单选框SelectField下拉列表SelectMultipleField下拉列表,可选择多个值FileField文件上传字段SubmitField表单提交按钮FormField把表单作为字段嵌入另一个表单FieldList一组指定类型的字段 以下是WTForms内建的验证函数: 验证函数说明Email验证电子邮件地址EqualTo比较两个字段的值;常用于密码确认IPAddress验证IPv4网络地址Length验证输入字符串的长度NumberRange验证输入的值在数字范围内Optional无输入值时跳过其他验证函数Required确保字段中有数据Regexp使用正则表达式验证输入值URL验证URLAnyOf确保输入值在可选值列表中NoneOf确保输入值不在可选值列表中 以下是几个字段和验证函数的使用示例asp表单,完整的使用示例和说明可参考末尾处提供的文档。
首先要导入字段函数,不过为了方便整个表单的使用,也可以直接使用from wtforms.fields import *的方式导入所有可用表单字段。PasswordField()方法的第一个参数是提示信息,第二个参数是验证函数,值是由验证函数组成的列表,用Required()可以设置必填项,EqualTo()用于匹配两个表单的输入,EqualTo()函数的第一个参数是需要进行比对的字段名称,第二个参数是匹配失败的时候的提示信息
与其它字段类似,第一个参数是名字,但目前还没有发现有什么用处,在前端也不显示。第二个参数就是单选按钮的各个选项,可以是元组类型组成的列表,元组的第一个参数是value的值,第二个参数是显示在页面前端的名字。如上代码在前端中是这样子的:
对,Jinja2默认地用两个div来分别显示这两个radio了,默认地在页面前端看到的就是一个在上一个在下
第一个参数是显示在页面的名字,第二个参数可设置是否默认选中,如果不设置或者为False,则不选中 4.3 把表单渲染成HTML 表单字段是可调用的,可以通过参数例如form传到模板中,然后可以在模板中生成一个简单的表单:
还可以把参数传入渲染字段的函数来改进表单的外观,传入的参数会被转换成字段的HTML属性。如下代码可以指定name字段的id属性:
当然其实Bootstrap已经为我们提供了一些表单样式,可以这样调用:
于是完整的表单代码如下: 修改 templates/index.html
4.4 在视图函数中处理表单 目前为止,表单在视图函数中定义了,而模板中也对表单数据进行了渲染,还没有把数据发送到模板,因此需要修改视图函数: 修改 hello.py
在app.route修饰器中添加了method参数,使得index()视图函数可以处理GET和POST请求,如果没有添加的话,则只能处理GET请求,而表单提交通常应使用POST请求。 由于在表单类中为name字段设置了验证函数,所以如果验证通过,则validate_on_submit()方法会返回True,否则返回False。首次加载页面时,由于表单中没有数据,因此会返回False,直接加载表单,而在填写了表单数据并验证难过后,服务器会收到一个POST请求,就可以把输入的数据赋值给name变量并传到模板中进行渲染。form.name.data = ''可以在获取了表单输入数据后清空输入框。 而如果验证没通过的话,点击提交按钮时会收到一个错误提醒。 4.5 重定向和用户会话 在当前版本的hello.py中,如果在输入名字后提交表单,再刷新时,会被提示是否要重新发送已填写数据。在多数情况下,这并不是个理想的处理方式。 使用重定向就可以很好地解决这个问题。Flask中把重定向当成一种特定的响应,其响应的内容是URL。 但还有一个问题,就是当程序处理POST请求结束后,表单中获取到的用户输入数据就丢失了,如果使用重定向,就不能继续使用这些数据。此时,就要使用到用户会话,也就是第2章中提到的session。 使用了重定向和用户会话后的视图函数如下所示: hello.py
本程序使用了用户会话session来替代了前面的局部变量name,所以在两次请求之间也能够记住输入的数据。 如上代码中,如果表单输入正确,则会调用到redirect()函数。该函数用于生成HTTP重定向响应,其参数是重定向的URL,它的第一个参数必须指定端点名,即路由内部的名字,默认情况下路由端点是相应视图函数的名字。 4.6 Flash消息 Flash消息用于显示确认消息、警告或者错误提醒。 来自Flask文档中的Flash消息闪现说明:闪现系统的基本工作方式是:在且只在下一个请求中访问上一个请求结束时记录的消息。也就是说,当前看到的Flash消息,是上一次请求结束后设置的。 在hello.py文件中使用Flash消息:
在示例中,每次提交的名字会跟存储在session中的上一次提交的名字做比较,如果不一样,则会调用flash()函数,在发给客户端的下一个响应中显示消息。 flash()函数返回的消息需要被模板接收渲染: 修改 templates/base.html
在模板中使用循环是因为在之前的请求循环中每次调用flash()函数时,都会生成一个消息,所以可能会有多个消息在排除等待显示。get_flashed_message()函数获取的消息在下次调用时不会再次返回,其实这个函数获取到的消息是一个列表。 WTForms表单的具体使用可参数官方文档WTForms Documentation Flash消息闪现的使用可参Flash文档-消息闪现 (编辑:通辽站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |