the flask mega tutorial自学记录 之 第三章 网页表单

  1. 安装Flask-WTF
    为了更搞笑的制作表单,需要安装一个flask的扩展包——flask-wtf。
pip install flask-wtf
  1. 配置块
    在APP中,我们经常会用到一些秘钥之类的配置,秉承先前独立原则,把配置块直接独立出来,在等级目录中建立一个配置文件config.py。
    另外为了防止Cross-Site Request Forgery(跨站点伪造请求),需要秘钥控制。
import os

class Config(object):
    #environ表示环境变量,
    #二次元操作:当系统有环境变量时就取名为SECRET_KEY的环境变量,否则赋值'you-will-never-guess'
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'

有了独立的配置后,又怎么让flask认得呢?在app/init.py中导入模块:

from flask import Flask
from config import Config      #导入刚才建立的Config模块

app = Flask(__name__)
app.config.from_object(Config)   #第一个小写config是app的属性,第二个大写Config是导入模块

3、登录页面表单字段设置,独立的模块app/forms.py:

#flask的扩展库一般是以flask_**来命名
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired

class LoginForm(FlaskForm):
    #各字段第一个参数值表示的是字段显示名称,DataRequired()用来验证数据是否为空
    username = StringField('Username', validators=[DataRequired()]) 
    password = PasswordField('Password', validators=[DataRequired()])
    remember_me = BooleanField('Remember Me')
    submit = SubmitField('Sign In')

4、登录页面模板设置app/templates/login.html,引用刚才建立的LoginForm模块中字段:

{% extends "base.html" %}

{% block content %}
    <h1>Sign In</h1>
    <form action="" method="post" novalidate>     #action表示向何处发送表单数据,为空代表当前地址
        {{ form.hidden_tag() }}   #生成一个隐藏的字段,防止CSRF攻击,一般同秘钥一起使用
        <p>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}  #size:输入字段的宽度
        </p>
        <p>
            {{ form.password.label }}<br>
            {{ form.password(size=32) }}  #size:输入字段的宽度
        </p>
        <p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
        <p>{{ form.submit() }}</p>
    </form>
{% endblock %}

5、在app/routes.py中增加login的视图函数

from flask import render_template, flash, redirect

@app.route('/login', methods=['GET', 'POST'])  #methods:访问请求方式
def login():
    form = LoginForm()
    if form.validate_on_submit():  #当浏览器传递的是Get方式时,validate_on_submit()返回False,如果Post方式时,所有字段如果验证通过方可返回True
        flash('Login requested for user {}, remember_me={}'.format(
            form.username.data, form.remember_me.data))   #flash生成一个提示闪现消息
        return redirect('/index')    # redirect:跳转页面
    return render_template('login.html', title='Sign In', form=form)

6、在base.html中增添闪现信息,通过列表方式展示。
其中遇到一个坑:{%…%}语法,如果在%符号前后加入空格的话,网页访问的时候,后台程序会报错,提示‘}’错误。

<html>
    <head>
        {% if title %}
        <title>{{ title }} - microblog</title>
        {% else %}
        <title>microblog</title>
        {% endif %}
    </head>
    <body>
        <div>
            Microblog:
            <a href="/index">Home</a>
            <a href="/login">Login</a>
        </div>
        <hr>
        {% with messages = get_flashed_messages() %}  #获取所有的闪现消息,list方式存储
        {% if messages %}
        <ul>
            {% for message in messages %}
            <li>{{ message }}</li>
            {% endfor %}
        </ul>
        {% endif %}
        {% endwith %}
        {% block content %}{% endblock %}
    </body>
</html>

7、登录页面录入信息校验,提示录入错误信息,文件app/templates/login.html。

{% extends "base.html" %}

{% block content %}
    <h1>Sign In</h1>
    <form action="" method="post" novalidate>
        {{ form.hidden_tag() }}
        <p>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}<br>
            {% for error in form.username.errors %}       #errors:错误信息
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.password.label }}<br>
            {{ form.password(size=32) }}<br>
            {% for error in form.password.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
        <p>{{ form.submit() }}</p>
    </form>
{% endblock %}

至此,运行flask后,最后的界面如下:
这里写图片描述
8、关于连接的探讨
在前边,我们共使用了两种连接方式。
其一:在导航栏模板中定义的导航项:

 <div>
        Microblog:
        <a href="/index">Home</a>
        <a href="/login">Login</a>
    </div>

其二:在登录模板中使用的跳转操作:

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        # ...
        return redirect('/index')
    # ...

这种方式直接写连接地址,会存在一个问题:如果后期需要修改连接地址的时候,你就需要查找到代码文件再修改,维护起来就困难。

Flask自带了一个很好的函数url_for()来处理此种问题.
url_for()使用url映射中保存的信息生成url。
url_for()的基本用法:

#通过视图函数映射
url_for(‘index’ name =’wang’,external=True)   #第一个参数index是视图函数名,第二个参数自定义的参数(可以起到拼接的效果)。
#通过静态文件映射
url_for('static',filename='css/styles.css',_external=True) 得到的结果:http://localhost:5000/static/css/styles.css

上边两种连接方式的改进方式如下:

    <div>
        Microblog:
        <a href="{{ url_for('index') }}">Home</a>    #index是视图函数名称
        <a href="{{ url_for('login') }}">Login</a>   #login是视图函数名称
    </div>
from flask import render_template, flash, redirect, url_for

# ...

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        # ...
        return redirect(url_for('index'))   #index是视图函数名称
    # ...

猜你喜欢

转载自blog.csdn.net/hawk_2016/article/details/81189298