基于flask的microBlog开发笔记(二)

4. flask表单初始化

  • 表单配置
    许多 Flask 扩展需要大量的配置,因此我们将要在 microblog/ 文件夹下创建一个配置文件以至于容易被编辑。这就是我们将要开始的(config.py)
1
2
CSRF_ENABLED = True
SECRET_KEY = 'bawel'

CSRF_ENABLED 配置是为了激活跨站点请求伪造保护,SECRET_KEY 配置仅仅当 CSRF 激活的时候才需要,它是用来建立一个加密的令牌,用于验证一个表单。当你编写自己的应用程序的时候,请务必设置一个很难被猜测到的密钥。当有了配置文件,我们需要告诉 Flask 去读取以及使用它。我们可以在 Flask 应用程序对象被创建后去做,方式如下(app/init.py)

1
2
3
4
5
6
from flask import Flask

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

from app import views

  • 用户登录表单

创建一个登录表单,用于用户认证系统。在我们应用程序中支持的登录机制是标准的用户名/密码类型 我们同时在表单上提供一个remember me的选择框,以至于用户可以选择在他们的网页浏览器上种植 cookie ,当他们再次访问的时候,浏览器能够记住他们的登录,编写第一个表单(app/forms.py)

1
2
3
4
5
6
7
8
from flask_wtf import Form
from wtforms import TextField, BooleanField, PasswordField
from wtforms.validators import Required

class LoginForm(Form):
name = TextField('Name', validators=[Required()])
password = PasswordField('password', validators=[Required()])
remember_me = BooleanField('Remember_me', default=False)

我们导入 Form 类,接着导入两个我们需要的字段类,TextField 和 BooleanField。Required 是一个验证器,一个函数,它能够作用于一个域,用于对用户提交的数据进行验证。 Required 验证器只是简单地检查相应域提交的数据是否是空。

  • 表单模板,我们刚刚创建的 LoginForm 类知道如何呈现为 HTML 表单字段,所以我们只需要集中精力在布局上。这里就是我们登录的模板(app/templates/login.html)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <!-- 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 Name:<br>
    {{form.name(size=80)}}<br>
    </p>
    <p>
    Password:<br>
    {{ form.password }}
    </p>
    <p>{{form.remember_me}} Remember Me?</p>
    <p><input type="submit" value="Sign In"></p>
    </form>
    {% endblock %}

base.html 模板通过 extends 模板继承声明语句,form.hidden_tag() 模板参数将被替换为一个隐藏字段,用来是实现在配置中激活的 CSRF 保护。如果已经激活了 CSRF,这个字段需要出现在所有的表单中。

  • 表单视图,(app/views.py)

    1
    2
    3
    4
    5
    6
    7
    from flask import render_template, flash, redirect
    from forms import LoginForm
    from app import app
    # 这里省略了索引函数
    @app.route('/login', methods = ['GET', 'POST'])
    def login():
    form = LoginForm()

    我们已经导入 LoginForm 类,从这个类实例化一个对象,接着把它传入到模板中。这就是我们渲染表单所有要做的。

5. 表单数据

  • 接收表单数据,flask-wtf处理提交的数据,登录视图函数更新的版本,它验证并且存储表单数据 (app/views.py)
1
2
3
4
5
6
7
8
9
10
11
@app.route('/login', methods = ['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
flash('Login requested for Name: ' + form.name.data)
flash('passwd: ' + str(form.password.data))
flash('remember_me: ' + str(form.remember_me.data))
return redirect('/index')
return render_template('login.html',
title = 'Sign In',
form = form)

当validate_on_submit 在表单提交请求中被调用,它将会收集所有的数据,对字段进行验证,如果所有的事情都通过的话,它将会返回 True,表示数据都是合法的。若有一个没通过验证,则返回false,接着表单会重新呈现给用户,这也将给用户一次机会去修改错误。当 validate_on_submit 返回 True,登录视图函数调用了两个新的函数,flash函数是一种快速的方式下呈现给用户的页面上显示一个消息。
*加强字段验证,当字段验证失败的时候, Flask-WTF 会向表单对象中添加描述性的错误信息。这些信息是可以在模板中使用的,因此我们只需要增加一些逻辑来获取它,这就是我们含有字段验证信息的登录模板(app/templates/login.html)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- 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.name(size=80)}}<br>
{% for error in form.errors.name %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}<br>
</p>
<p>
Password:<br>
{{form.pawword}}<br>
{% for error in form.errors.password %}
<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 %}