Flask实践Step by Step -- Web表单

Flask开发环境配置
Flask快速入门
Flask实践Step by Step -- 'Hello World'
Flask实践Step by Step -- 模板
Flask实践Step by Step -- Web表单

Flask Web Forms

上一节我们定义了一个简单的模板,并看到了实际运行的效果,接下来我们来看一下Web表单是如何
工作的,Web表单是Web应用程序的基础控件,使用表单可以使用用户写博客,进行登录等

配置

为了使用表单,我们需要使用Flask的一个扩展插件 Flask-WTF 需要先安装 pip install flask-wtf ,
许多Flask扩展需要很多的配置,我需要一个配置文件来进行管理 config.py

WTF_CSRF_ENABLED = True
SECRET_KEY = 'you-will-never-guess'

配置文件中的内容非常简单,需要两项设置即可,WTF_CSRF_ENABLED设置会激活跨站访问保护
这个设置在这个版本中Flask-WTF是默认打开的,为了更安全我们这里还是显示的设置为 True
SECRECT_KEY的设置只有当WTF_CSRF_ENABLED为true时才会需要,为表单验证创建一个密码
token,这个key值尽量设置的复杂一些
接下来就需要Flask读取相关的配置,并且使用这些配置,在Flask的应用程序创建之后(file app/__init__.py)

from flask import Flask

app = Flask(__name__)
app.config.from_object('config')

from app import views

用户登录表单

Flask-WTF的表单是一个集成基类Form的一个类,现在我们需要创建一个登录的表单,需要用到身份认证系统
登录机制不是标准的 用户名/密码 模式,我们在这里引入了 OpendID,OpenID本身已经提供了
很好的验证,我们就不在需要验证密码了,这样可以使网站更安全,需要安装OpenID pip install flask-openid
使用OpenID登录只需要一个字符串,我们还提供了一个 'remember me' 选择框,用户可以选择是否需要浏览器在cookie中记住
用户的选择
写第一个表单 (file 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)

很简单的一个类,继承Form两个字段,StringFieldBooleanField,DataRequired是一个验证器
一个方法和一个字段绑定,这个DataRequired验证器只是简单的验证提交的输入内容,这Flask-WTF中还有很多
验证器,后续会继续介绍

表单模板

我们需要一个模板来生成HTML的表单,我们需要创建一个新的模板 (file app/templates/login.html)

{% extends "base.html" %}

{% block content %}
  

Sign in

{{form.hidden_tag()}}

Please enter your OpenID:
{{ form.openid(size=80) }}

{{ form.remember_me }} Remember Me

{% endblock %}

这个模板中同样是继承base.html,这个模板和普通的HTML页面的表单还是有一些区别的,需要
视图中对应的方法来血染这个模板,form.hidden_tag()会被HTML中的隐藏的域来取代,这个参数
需要把CSRF设置为Enabled状态

表单视图

我们需要一个视图方法来渲染这个模板(file app/views.py)

from flask import render_template,flash,redirect
from app import app
from .forms import LoginForm

#index view function...

@app.route('/login',methods=['GET','POST'])
def login():
    form = LoginForm()
    return render_template('login.html',
                            title="Sign in",
                            form=form)

需要引入 LoginForm这类,然后实例化,将这个实例化对象作为参数传入到模板中,我们还引入了
flashredirect,可以暂时忽略这两个引用,以后我们会用到,在装饰器中我们加入了 methods
作为参数,告诉Flask我们的这个方法接收 GET和POST请求,保存运行,打开浏览器 访问 http://127.0.0.1:5000/login
看一下实际的效果,暂时我们还没有处理接收数据的处理,所以现在点击提交按钮会没有任何反馈

接收数据

Flask-WTF能够很容易处理从客户端发来的数据,我们需要修改一下 login的方法(file app/views.py)

@app.route('/login',methods=['GET','POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        flash('Login requested for OpenID=""%s",remember_me=%s'%
                (form.openid.data,str(form.remember_me.data)))
        return redirect('/index')
    return render_template('login.html',
                            title="Sign in",
                            form=form)

方法 validate_on_submit会处理所有的表单的处理工作,表单展示给用户时会调用这个方法此时会返回 False
当提交请求时,这个方法会接收所有的数据,验证数据的合法性,如果验证全部正确,这个方法会返回True,只要有一个
参数验证不通过,这个方法就会返回 False,稍后我们会展示如何给用户展示错误信息,当 validate_on_submit返回True
时,方法 flash会展示一个快速的信息,在调到下一个页面之前,这个flash的信息不回显示在页面中,我们需要修改模板信息
来显示这个信息(file app/templates/base.html)



  
    
    {% if title %}
    {{ title }} - microblog
    {% else %}
    Welcome to microblog
    {% endif %}
  
  
    
Microblog : Home

{% with messages = get_flashed_messages()%} {% if messages %}
    {% for msg in messages %}
  • {{ msg }}
  • {% endfor %}
{% endif %} {% endwith %} {% block content %}{% endblock %}

方法get_flashed_messages会接收flash方法发送来的消息,并展示出来,在视图方法中我们还使用另一个
方法 redirect,这个方法会重定向到另一网页地址

改进数据的验证

当用户的输入的信息有误时,希望能够提供给用户友好的错误的信息提示,我们修改一下login的模板(file app/templates/login.html)

{% extends "base.html" %}

{% block content %}
  

Sign in

{{form.hidden_tag()}}

Please enter your OpenID:
{{ form.openid(size=80) }} {% for error in form.openid.errors %} [{{ error }}] {% endfor %}

{{ form.remember_me }} Remember Me

{% endblock %}

添加了错误的提示信息

处理OpenIDs

为了是用户更容易的登录网站,我们添加一些openid的连接,儿不需要用户手动的输入OpenID
先定义一些OpenID的提供者,定义在config.py

WTF_CSRF_ENABLED = True
SECRET_KEY = 'you-will-never-guess'

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/'},
    {'name': 'Flickr', 'url': 'http://www.flickr.com/'},
    {'name': 'MyOpenID', 'url': 'https://www.myopenid.com'}]

然后在视图方法中使用

@app.route('/login',methods=['GET','POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        flash('Login requested for OpenID=""%s",remember_me=%s'%
                (form.openid.data,str(form.remember_me.data)))
        return redirect('/index')
    return render_template('login.html',
                            title="Sign in",
                            form=form,
                            providers=app.config['OPENID_PROVIDERS'])

还需要修改对应的模板视图(file app/templates/login.html)

{% extends "base.html" %}

{% block content %}



  

Sign in

{{form.hidden_tag()}}

Please enter your OpenID:
{{ form.openid(size=80) }} {% for error in form.openid.errors %} [{{ error }}] {% endfor %}
| {% for pr in providers %} {{ pr.name }} | {% endfor %}

{{ form.remember_me }} Remember Me

{% endblock %}
Flask实践Step by Step -- Web表单_第1张图片
运行截图

写在最后

我们队登录的表单做了很多的改进,但是我们还没有真正的登录到系统中,真正的登录我们需要后台的数据库的支持

你可能感兴趣的:(Flask实践Step by Step -- Web表单)