title: flask学习笔记
subtitle: 3. flask Web表单
date: 2018-12-14 10:17:28
---
Web表单
HTML表单是用户和web站点或应用程序之间交互的主要内容之一。它们允许用户将数据发送到web站点。大多数情况下,数据被发送到web服务器,但是web页面也可以自己拦截它并使用它。
HTML表单是由一个或多个小部件组成的。这些小部件可以是文本字段(单行或多行)、选择框、按钮、复选框或单选按钮。大多数情况下,这些小部件与描述其目的的标签配对——正确实现的标签能够清楚地指示视力正常的用户和盲人用户输入表单所需的内容。
HTML 表单-示例:
Flask-WTF插件
Flask-WTF插件来处理本应用中的Web表单,它对WTForms进行了浅层次的封装以便和Flask完美结合
配置
最基本的解决方案是使用app.config对象,它是一个类似字典的对象,可以将配置以键值的方式存储其中。松耦和,配置和应用代码分开放置
Flask及其一些扩展使用密钥的值作为加密密钥,用于生成签名或令牌。Flask-WTF插件使用它来保护网页表单免受名为Cross-Site Request Forgery或CSRF(发音为“seasurf”)的恶意攻击。
密钥被定义成由or运算符连接两个项的表达式。第一个项查找环境变量SECRET_KEY的值,第二个项是一个硬编码的字符串。这种首先检查环境变量中是否存在这个配置,找不到的情况下就使用硬编码字符串的配置变量的模式你将会反复看到。在开发阶段,安全性要求较低,因此可以直接使用硬编码字符串。但是,当应用部署到生产服务器上的时候,我将设置一个独一无二且难以揣摩的环境变量,这样,服务器就拥有了一个别人未知的安全密钥了。
config.py:
import osclass Config(object):SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'app/__init__.py:
from flask import Flask
from config import Configapp = Flask(__name__)
app.config.from_object(Config)from app import routes
配置2
CSRF_ENABLED 配置是为了激活 跨站点请求伪造 保护。在大多数情况下,需要激活该配置使得应用程序更安全些。
SECRET_KEY 配置仅仅当 CSRF 激活的时候才需要,它是用来建立一个加密的令牌,用于验证一个表单。当你编写自己的应用程序的时候,请务必设置很难被猜测到密钥。
config.py:
CSRF_ENABLED = True
SECRET_KEY = 'you-will-never-guess'app/__init__.py:
from flask import Flaskapp = Flask(__name__)
app.config.from_object('config')from app import views
Flask Web表单
Flask Web表单由三部分构成,用户登录表单,表单模板,表单视图。用户登录表单定义HTML网页上的数据。表单模板将表单添加到HTML模板以便渲染到网页。表单视图创建form实例,并将其传入渲染模板的函数中,然后用*/login* URL来关联它。
用户登录表单
# @File : forms.py
# @Software: PyCharm# from flask_wtf import FlaskForm
# from wtforms import StringField, BooleanField
# from wtforms.validators import DataRequired
#
#
# class LoginForm(FlaskForm):
# openid = StringField('openid', validators=[DataRequired()])
# remember_me = BooleanField('remember_me', default=False)from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequiredclass LoginForm(FlaskForm):username = StringField('Username', validators=[DataRequired()])password = PasswordField('Password', validators=[DataRequired()])remember_me = BooleanField('Remember Me')submit = SubmitField('Sign In')
表单模板(.html文件)
HTML<\form>元素被用作Web表单的容器。 表单的action属性告诉浏览器在提交用户在表单中输入的信息时应该请求的URL。 当action设置为空字符串时,表单将被提交给当前地址栏中的URL,即当前页面。 method属性指定了将表单提交给服务器时应该使用的HTTP请求方法。 默认情况下是用GET请求发送,但几乎在所有情况下,使用POST请求会提供更好的用户体验,因为这种类型的请求可以在请求的主体中提交表单数据, GET请求将表单字段添加到URL,会使浏览器地址栏变得混乱。
<!-- extend from base layout -->
{% extends "base.html" %}{% block content %}
<h1>Sign In</h1>
{#<form action="" method="post" name="login">#}
{# {{form.hidden_tag()}}#}
{# <p>#}
{# Please enter your OpenID:<br>#}
{# {{form.openid(size=80)}}<br>#}
{# </p>#}
{# <p>{{form.remember_me}} Remember Me</p>#}
{# <p><input type="submit" value="Sign In"></p>#}
{#</form>#}<form action="" method="post" novalidate>{{ form.hidden_tag() }}<p>{{ form.username.label }}<br>{{ form.username(size=32) }}</p><p>{{ form.password.label }}<br>{{ form.password(size=32) }}</p><p>{{ form.remember_me() }} {{ form.remember_me.label }}</p><p>{{ form.submit() }}</p></form>
{% endblock %}
表单视图
form.validate_on_submit()实例方法会执行form校验的工作。当浏览器发起GET请求的时候,它返回False,这样视图函数就会跳过if块中的代码,直接转到视图函数的最后一句来渲染模板。
当用户在浏览器点击提交按钮后,浏览器会发送POST请求。form.validate_on_submit()就会获取到所有的数据,运行字段各自的验证器,全部通过之后就会返回True,这表示数据有效。不过,一旦有任意一个字段未通过验证,这个实例方法就会返回False,引发类似GET请求那样的表单的渲染并返回给用户。稍后我会在添加代码以实现在验证失败的时候显示一条错误消息。
当form.validate_on_submit()返回True时,登录视图函数调用从Flask导入的两个新函数。 flash()函数是向用户显示消息的有效途径。 许多应用使用这个技术来让用户知道某个动作是否成功。我将使用这种机制作为临时解决方案,因为我没有基础架构来真正地登录用户。 显示一条消息来确认应用已经收到登录认证凭据,我认为对当前来说已经足够了。
登录视图函数中使用的第二个新函数是redirect()。这个函数指引浏览器自动重定向到它的参数所关联的URL。当前视图函数使用它将用户重定向到应用的主页。
# @File : views.py
# @Software: PyCharm# from flask import render_template
# render_template函数需要传入模板名以及一些模板变量列表,返回一个所有变量被替换的渲染的模板。
from app import app
from flask import render_template, flash, redirect
from .forms import LoginForm# index view function suppressed for brevity
@app.route('/login', methods=['GET', 'POST'])
def login():form = LoginForm()# if form.validate_on_submit():# flash('Login requested for OpenID="' + form.openid.data + '", remember_me=' + str(form.remember_me.data))# return redirect('/index')# return render_template('login.html', title='Sign In', form=form)if form.validate_on_submit():flash('Login requested for user {}, remember_me={}'.format(form.username.data, form.remember_me.data))return redirect('/index')return render_template('login.html', title='Sign In', form=form)