2020-06-02--flask04--flask基础04
- jinja2模板
- 表单验证
- WTF表单验证
jinjia2语法
过滤器
jinja2的过滤器与django中的过滤器很相似
用法:
{{ 变量|过滤器 参数 }}
对于字符串的过滤器:
- safe:禁用转义;
<p>{{ '<em>hello</em>' | safe }}</p>
- capitalize:把变量值的首字母转成大写,其余字母转小写;
<p>{{ 'hello' | capitalize }}</p>
- lower:把值转成小写;
<p>{{ 'HELLO' | lower }}</p>
- upper:把值转成大写;
<p>{{ 'hello' | upper }}</p>
- title:把值中的每个单词的首字母都转成大写;
<p>{{ 'hello' | title }}</p>
- trim:把值的首尾空格去掉;
<p>{{ ' hello world ' | trim }}</p>
- reverse:字符串反转;
<p>{{ 'olleh' | reverse }}</p>
- format:格式化输出;
<p>{{ '%s is %d' | format('name',17) }}</p>
- striptags:渲染之前把值中所有的HTML标签都删掉;
<p>{{ '<em>hello</em>' | striptags }}</p>
对于列表的过滤器:
- first:取第一个元素
<p>{{ [1,2,3,4,5,6] | first }}</p>
- last:取最后一个元素
<p>{{ [1,2,3,4,5,6] | last }}</p>
- length:获取列表长度
<p>{{ [1,2,3,4,5,6] | length }}</p>
- sum:列表求和
<p>{{ [1,2,3,4,5,6] | sum }}</p>
- sort:列表排序
<p>{{ [6,2,3,1,5,4] | sort }}</p>
数值过滤器
<h2>数值过滤器</h2>
<p>{{ 1.5|round }}</p> {# 四舍五入,返回float #}
<p>{{ 12.8888 | round(2, 'floor') }}</p> {# 保留两位小数,向下取 #}
<p>{{ -2|abs }}</p> {# 绝对值 #}
自定义过滤器
我们自定义过滤器依旧可以采用装饰器的方式进行定义,也可以通过app内注册的方式实现它,如果没有给过滤器名称,则过滤器默认同样为函数名。
#自定义过滤器
#1.
@app.template_filter('absp') #装饰器的参数为自定义的过滤器名称
def abspuls(num):
num = abs(num)
num+=1
return num
#2.
def abspuls(num):
num = abs(num)
num += 1
return num
app.add_template_filter(abspuls,'absp') #第一个参数为函数名,第二个参数为自定义的过滤器名
<p>{{ -2|absp }}</p> {# 使用自定义的过滤器 #}
Web表单
web表单是web应用程序的基本功能。
它是HTML页面中负责数据采集的部件。表单有三个部分组成:表单标签、表单域、表单按钮。表单允许用户输入数据,负责HTML页面数据采集,通过表单将用户输入的数据提交给服务器。
在django中,有forms模块帮助我们验证表单,
在Flask中,为了处理web表单,我们一般使用Flask-WTF扩展,它封装了WTForms,并且它有验证表单数据的功能
WTF表单验证
Flask-WTF是集成WTForms,并带有 csrf 令牌的安全表单和全局的 csrf 保护的功能。
每次我们在建立表单所创建的类都是继承与flask_wtf中的FlaskForm,而FlaskForm是继承WTForms中forms。使用Flask-WTF表单扩展,可以帮助进行CSRF验证,帮助我们快速定义表单模板,而且可以帮助我们在视图中验证表的数据。
常用WTForms的验证函数:
验证函数 | 说明 |
---|---|
DataRequired | 确保字段中有数据 |
EqualTo | 比较两个字段的值,常用于比较两次密码输入 |
Length | 验证输入的字符串长度 |
NumberRange | 验证输入的值在数字范围内 |
URL | 验证URL |
AnyOf | 验证输入值在可选列表中 |
NoneOf | 验证输入值不在可选列表中 |
form表单的action属性默认提交给当前地址栏的url
不使用WTF表单验证
app.secret_key = 'defwefwfwef'
@app.route('/login',methods=['GET','POST'])
def login():
if request.method == 'POST':
#获取表单的参数
uname = request.form.get('username','')
pwd = request.form.get('password','')
pwd2 = request.form.get('password2','')
if not all([uname,pwd,pwd2]):
flash('参数不足') #向前端展示一个参数
elif pwd != pwd2:
flash('密码不一致')
else:
print(uname,pwd,pwd2)
return "success"
# return redirect(url_for('tranfer'))
return render_template('login.html')
html:
<body>
<h1>登录页面</h1>
<form action="" method="POST">
<label for="uname">username:</label>
<input type="text" name="username" id="uname" placeholder="请输入用户名">
<br><br>
<label for="text">password:</label>
<input type="text" name="password" id="text" placeholder="请输入密码">
<br><br>
<label for="text">pwdagain:</label>
<input type="text" name="password2" id="text" placeholder="确认密码">
<br><br>
<input type="submit" value="登录">
</form>
#用于显示flash值
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
运行:
访问:127.0.0.1:5000/login
使用WTF表单验证
新建一个demo_wtf2.py:
from flask import Flask, request, render_template, flash
app = Flask(__name__)
app.secret_key = 'adasfsads'
if __name__ == '__main__':
app.run(debug=True)
flash的主要功能是渲染消息通知,由于不需要编写前后端通道即可渲染消息,可以称为消息闪现。
在demo_wtf2内创建一个基础表单,其中validators字段的作用是调用WTF的验证函数,所需的所有验证函数应依次存于后继的列表内部。render_kw字段主要用于填充html,这样就不必在前端书写。
RegisterForm类:
#自定义表单类
class RegisterForm(FlaskForm):
username = StringField("用户名:",validators=[DataRequired("请输入用户名:")],render_kw={"placeholder":"请输入用户名"})
password = PasswordField("密码",validators=[DataRequired ("请输入密码")],render_kw={"placeholder":"请输入密码"})
password2 = PasswordField("确认密码",validators=[DataRequired ("请确认密码"),EqualTo('password','密码不一致')],render_kw={"placeholder":"请确认密码"})
submit = SubmitField("登录")
视图函数:
@app.route('/login2',methods=['GET','POST'])
def login2():
# 实例化表单类
register_form = RegisterForm()
if register_form.validate_on_submit():
# 如果代码走到if里面证明表单验证有效
username = request.form.get("username")
password = request.form.get("password", "")
password2 = request.form.get("password2", "")
print(username, password, password2)
return "success"
else:
if request.method == 'POST':
flash("表单参数有误或者不完整")
return render_template('login2.html',form = register_form)
html:
<body>
<h1>WTF表单</h1>
<form method="post">
{{ form.username.laebel }}{{ form.username }}<br>
{{ form.password.laebel }}{{ form.password }}<br>
{{ form.password2.laebel }}{{ form.password2 }}<br>
{{ form.submit }}
</form>
#flash信息
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
</body>
分析:当使用get方式访问login2页面时,获取表单验证中的信息,表单验证不合法并且不是post请求,直接返回携带表单信息的login2.html页面。
当用户填写了表单信息后,使用post提交给服务器,在表单验证类中验证如果合法,获取各个信息值,返回success,如果不合法,进入else,并且方法为post,就返回flash的值。
运行:127.0.0.1:5000/login2
填写正确的情况:
返回success
错误的情况:
闪现flash的值:
app.config['WTF_CSRF_ENABLED'] = False
关闭csrf的验证
代码:
demo_wtf.py:
from flask import Flask, render_template, request, flash
from flask_wtf import FlaskForm
from wtforms import StringField,PasswordField,SubmitField #字符串,密码,提交按钮 字段
from wtforms.validators import DataRequired, EqualTo # 保证字段中有数据,是否一致
app = Flask(__name__)
#自定义表单类
class RegisterForm(FlaskForm):
username = StringField("用户名:",validators=[DataRequired("请输入用户名:")],render_kw={"placeholder":"请输入用户名"})
password = PasswordField("密码",validators=[DataRequired ("请输入密码")],render_kw={"placeholder":"请输入密码"})
password2 = PasswordField("确认密码",validators=[DataRequired ("请确认密码"),EqualTo('password','密码不一致')],render_kw={"placeholder":"请确认密码"})
submit = SubmitField("登录")
app.secret_key = 'defwefwfwef'
app.config['WTF_CSRF_ENABLED'] = False #关闭csrf的验证
@app.route('/login2',methods=['GET','POST'])
def login2():
# 实例化表单类
register_form = RegisterForm()
if register_form.validate_on_submit():
# 如果代码走到if里面证明表单验证有效
username = request.form.get("username")
password = request.form.get("password", "")
password2 = request.form.get("password2", "")
print(username, password, password2)
return "success"
else:
if request.method == 'POST':
flash("表单参数有误或者不完整")
return render_template('login2.html',form = register_form)
if __name__ == '__main__':
app.run(debug=True)