Flask03-Form
## Web 表单 配置
为了能够处理 web 表单,我们将使用 Flask-WTF ,该扩展封装了 WTForms 并且恰当地集成进 Flask 中。
许多 Flask 扩展需要大量的配置,因此我们将要在 microblog 文件夹的根目录下创建一个配置文件以至于容易被编辑。这就是我们将要开始的(文件 config.py):
$ config.py
> CSRF_ENABLED = True
> SECRET_KEY = 'you-will-never-guess'
// 告诉 Flask 去读取配置文件 app/__init__.py
> from flask import Flask
>
> app = Flask(__name__)
> app.config.from_object('config')
>
> from app import views
## 用户登录表单
在 Flask-WTF 中,表单是表示成对象,Form 类的子类。一个表单子类简单地把表单的域定义成类的变量。
我们将要创建一个登录表单,用户用于认证系统。在我们应用程序中支持的登录机制不是标准的用户名/密码类型,我们将使用 OpenID。OpenIDs 的好处就是认证是由 OpenID 的提供者完成的,因此我们不需要验证密码,这会让我们的网站对用户而言更加安全。
OpenID 登录仅仅需要一个字符串,被称为 OpenID。我们将在表单上提供一个 ‘remember me’ 的选择框,以至于用户可以选择在他们的网页浏览器上种植 cookie ,当他们再次访问的时候,浏览器能够记住他们的登录。
$ vim app/forms.py
> from flask.ext.wtf import Form
> from wtforms import StringField, BooleanField
> from wtforms.validators import DataRequired
>
> class LoginForm(Form):
> openid = StringField('openid', validators=[DataRequired()])
> remember_me = BooleanField('remember_me', default=False)
## 表单模板
$ vim app/templates/login.html
> <!-- 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=)}}<br>
> </p>
> <p>{{form.remember_me}} Remember Me</p>
> <p><input type="submit" value="Sign In"></p>
> </form>
> {% endblock %}
## 表单视图
$ vim app/views.py
> from flask import render_template, flash, redirect
> from app import app
> from .forms import LoginForm
>
> # index view function suppressed for brevity
>
> @app.route('/login', methods = ['GET', 'POST'])
> def login():
> form = LoginForm()
> return render_template('login.html',
> title = 'Sign In',
> form = form)
## 接收表单数据
// 验证表达数据是否正确(form.validate_on_submit),调用flash()显示消息
$ vim app/views.py
> @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)
// flash显示消息
$ vim app/templates/base.html
<html>
<head>
{% if title %}
<title>{{title}} - microblog</title>
{% else %}
<title>microblog</title>
{% endif %}
</head>
<body>
<div>Microblog: <a href="/index">Home</a></div>
<hr>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }} </li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</body>
</html>
## 加强字段验证
$ vim app/templates/login.html
> <!-- extend 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=) }}<br>
> {% for error in form.openid.errors %}
> <span style="color: red;">[{{ error }}]</span>
> {% endfor %}<br>
> </p>
> <p>{{ form.remember_me }} Remember Me</p>
> <p><input type="submit" value="Sign In"></p>
> </form>
> {% endblock %}
## 处理 OpenIDs
$ vim config.py
> OPENID_PROVIDERS = [
> { 'name': 'Google', 'url': 'https://www.google.com/accounts/o8/id' },
> { 'name': 'Yahoo', 'url': 'https://me.yahoo.com' },
> { 'name': 'AOL', 'url': 'http://openid.aol.com/<username>' },
> { 'name': 'Flickr', 'url': 'http://www.flickr.com/<username>' },
> { 'name': 'MyOpenID', 'url': 'https://www.myopenid.com' }]
$ vim app/view.py
> return render_template('login.html',
> title = 'Sign In',
> form = form,
> providers = app.config['OPENID_PROVIDERS'])
$ vim app/templates/login.html)
> <!-- extend base layout -->
> {% extends "base.html" %}
>
> {% block content %}
> <script type="text/javascript">
> function set_openid(openid, pr)
> {
> u = openid.search('<username>')
> if (u != -) {
> // openid requires username
> user = prompt('Enter your ' + pr + ' username:')
> openid = openid.substr(, u) + user
> }
> form = document.forms['login'];
> form.elements['openid'].value = openid
> }
> </script>
> <h1>Sign In</h1>
> <form action="" method="post" name="login">
> {{ form.hidden_tag() }}
> <p>
> Please enter your OpenID, or select one of the providers below:<br>
> {{ form.openid(size=) }}
> {% for error in form.openid.errors %}
> <span style="color: red;">[{{error}}]</span>
> {% endfor %}<br>
> |{% for pr in providers %}
> <a href="javascript:set_openid('{{ pr.url }}', '{{ pr.name }}');">{{ pr.name }}</a> |
> {% endfor %}
> </p>
> <p>{{ form.remember_me }} Remember Me</p>
> <p><input type="submit" value="Sign In"></p>
> </form>
> {% endblock %}
Flask03-Form的更多相关文章
- form表单验证-Javascript
Form表单验证: js基础考试内容,form表单验证,正则表达式,blur事件,自动获取数组,以及css布局样式,动态清除等.完整代码如下: <!DOCTYPE html PUBLIC &qu ...
- Form 表单提交参数
今天因为要额外提交参数数组性的参数给form传到后台而苦恼了半天,结果发现,只需要在form表单对应的字段html空间中定义name = 后台参数名 的属性就ok了. 后台本来是只有模型参数的,但是后 ...
- s:form标签
2017-01-07 17:43:18 基本的用法 <!-- Action类必须有一个无参的构造器,因为在执行action方法之前,拦截器已经创建了一个"空"的Action对 ...
- ASP.NET Aries JSAPI 文档说明:AR.Form、AR.Combobox
AR.Form 文档 1:对象或属性: 名称 类型 说明 data 属性 编辑页根据主键请求回来的数据 method 属性 用于获取数据的函数指向,默认值Get objName 属性 用于拦截form ...
- form表单 ----在路上(15)
form 表单就是将用户的信息提交到服务器,服务器会将信息存储活着根据信息查询数据进行增删改查,再将其返回给用户. 基本格式: <form action="" method ...
- 了解HTML表单之form元素
前面的话 表单是网页与用户的交互工具,由一个<form>元素作为容器构成,封装其他任何数量的表单控件,还有其他任何<body>元素里可用的标签 表单能够包含<input& ...
- form表单的字符串进行utf-8编码
<form>表单有assept-charset属性.该属性规定字符的编码方式,默认是"unknown",与文档的字符集相同. 该属性除了Internet explore ...
- js Form.elements[i]的使用实例
function pdf(){ //一个html里面可能存在多个form,所以document.form[0]指的是第一个form,document.form[1]返回就是第二个form,如果没 ...
- PHP跨域form提交
因为安全性因素,直接跨域访问是不被允许的. 1.PHP CURL方式 function curlPost($url,$params) { $postData = ''; foreach($params ...
- C#模拟HTTP Form请求上传文件
using System; using System.Collections.Generic; using System.Text; using System.Net; using System.IO ...
随机推荐
- Rocket - interrupts - Crossing
https://mp.weixin.qq.com/s/nSX4prXFb4K5GSUhPtOUCg 简单介绍Crossing的实现. 1. IntXing 这是一个LazyModule: 1) 参数 ...
- 【Kafka】知识总结
Kafka是什么? Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据. Kafka架构 1)点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除) 点对 ...
- [leetcode] 动态规划(Ⅰ)
这次按通过率从高到低刷题. 本文完成的题目:{338, 1025, 303, 121, 53, 392, 70, 746, 198} ,带有「面试」Tag 的题目:Interview - {1617, ...
- Java实现蓝桥杯历届试题格子刷油漆
问题描述 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆. 你可以从任意一个格子刷起,刷完一格,可以移动到和它相邻的格子(对角相邻也算数),但不能移动 ...
- Java实现 LeetCode 486 预测赢家
486. 预测赢家 给定一个表示分数的非负整数数组. 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端拿取分数,然后玩家1拿,--.每次一个玩家只能拿取一个分数,分数被拿取之后不再可 ...
- Java实现 蓝桥杯VIP 算法训练 学做菜
算法训练 学做菜 时间限制:1.0s 内存限制:256.0MB 问题描述 涛涛立志要做新好青年,他最近在学做菜.由于技术还很生疏,他只会用鸡蛋,西红柿,鸡丁,辣酱这四种原料来做菜,我们给这四种原料标上 ...
- Java实现 蓝桥杯VIP 算法训练 黑色星期五
有些西方人比较迷信,如果某个月的13号正好是星期五,他们就会觉得不太吉利,用古人的说法,就是"诸事不宜".请你编写一个程序,统计出在某个特定的年份中,出现了多少次既是13号又是星期 ...
- Java实现 LeetCode 58 最后一个单词的长度
58. 最后一个单词的长度 给定一个仅包含大小写字母和空格 ' ' 的字符串 s,返回其最后一个单词的长度. 如果字符串从左向右滚动显示,那么最后一个单词就是最后出现的单词. 如果不存在最后一个单词, ...
- java实现最大连续和问题
/* 10 5 -3 12 -31 15 22 -7 6 -8 -9 10 .... 暴力:O(n^3) 分治:[ mid ) 三种情况求最大 基线法: O(n) 2个数组: 从左到本位:出现的最大累 ...
- 【JAVA习题二十八】海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子凭据分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的,问海滩上原来最少有多少个桃子?
package erase; import java.util.Scanner; public class 猴子分桃 { public static void main(String[] args) ...