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


本节主要是制作一个会员注册页面,同时针对有些字段进行验证。如果提交数据都没有问题就是出现一个闪现消息:通知验证OK。

一、安装Flask-WTF模块

为了更高效的制作表单,引用一个瘦小的form包装器WTForms,现已有此功能的一个flask扩展包——flask-wtf。

pip install flask-wtf

二、配置

1、我们可以在初始化时添加配置:

init.py(两下划线不显示)

app = Flask(__name__)
app.config['SECRET_KEY'] = 'you-will-never-guess'
# ... add more variables here as needed

2、独立配置模块

在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'

3、应用配置类对象

由于我们在前边的配置模块中定义了Config类,又怎么让flask识别并添加配置呢?
还好,模块中已有一个方法:app.config.from_object()
在app/init.py中导入模块:

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

app = Flask(__name__)
app.config.from_object(Config)   #第一个小写config是模块,第二个大写config模块中定义的Config类

三、用户登录表单

在web中,每一个表单是一个个tag。但是,在python中,是用一个个类来呈现表单。通过一个类类定义各个字段。
构建表单模块
app/forms.py:

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

#请注意添加FlaskForm,否则在视图函数的validate_on_submit属性将不能被引用
class LoginForm(FlaskForm):
    #各字段第一个参数值表示的是字段显示名称,DataRequired()用来验证数据是否为空
    username = StringField('Username', validators=[DataRequired()]) 
    password = PasswordField('Password', validators=[DataRequired()])
    remember_me = BooleanField('Remember Me')
    submit = SubmitField('Sign In')

四、表单模板

构建LoginForm模块:
app/templates/login.html

{% 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 %}

Tip:
1、{{ form.<field_name>.label }}:获取表单字段的属性值
2、{{ form.<field_name>() }}:括号内参数是给html元素添加属性值
3、{{form.<field_name>}}:获取表单字段

五、表单视图

增加login的视图函数
app/routes.py

from flask import render_template
from app import app
from app.forms import LoginForm

# ...

@app.route('/login')
def login():
    form = LoginForm()
    return render_template('login.html', title='Sign In', form=form)

六、获取表单数据

1、提交方式及表单数据验证

validate_on_submit():
a、如果浏览器是发送GET方式,返回False;
b、如果POST方式且各表单字段验证通过,则返回True。

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)

2、Html设置闪现信息

虽然上边我们设置了flash信息,但是还不会显示出来。
其中遇到一个坑:{%…%}语法,如果在%符号前后加入空格的话,网页访问的时候,后台程序会报错,提示‘}’错误。
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>

七、改进字段验证

在会员注册的时候,总会有些录入错误,导致一些无效的注册。为了解决这个问题,最好的方式就是增加曾端验证。
登录页面录入信息校验,当检测到错误时,提示友好的录入指导信息。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后,最后的界面如下:
这里写图片描述

八、生成连接

在前边,我们共使用了两种连接方式。
其一:在导航栏模板中定义的导航项:

 <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()的两个优点:
a、url相比视图函数更可能会变动
b、url会带有一些动态的参数,如果手工拼写就会是很痛苦的。

url_for()的基本用法:
第一个参数是endpoint(URL的端点),即视图函数名称。
第二个参数是一些命名参数。

#通过视图函数映射
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是视图函数名称
    # ...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值