模板其实是一个包含响应文本的文件,其中用占位符(变量)表示动态部分,告诉模板引擎其具体的值需要从使用的数据中获取
使用真实值替换变量,再返回最终得到的字符串,这个过程称为“渲染”
Flask是使用 Jinja2 这个模板引擎来渲染模板
使用模板的好处:
视图函数只负责业务逻辑和数据处理(业务逻辑方面)
而模板则取到视图函数的数据结果进行展示(视图展示方面)
代码结构清晰,耦合度低
**Jinja2:**是 Python 下一个被广泛应用的模板引擎,是由Python实现的模板语言,他的设计思想来源于 Django 的模板引擎,并扩展了其语法和一系列强大的功能,其是Flask内置的模板语言。
**模板语言:**是一种被设计来自动生成文档的简单文本格式,在模板语言中,一般都会把一些变量传给模板,替换模板的特定位置上预先定义好的占位变量名。
Flask提供的 render_template 函数封装了该模板引擎
render_template 函数的第一个参数是模板的文件名,后面的参数都是键值对,表示模板中变量对应的真实值。
{# 这是注释 #}
{ { post.title }}
Jinja2 模版中的变量代码块可以是任意Python类型或者对象,只要它能够被Python的str()方法转换为一个字符串就可以,比如,可以通过下面的方式显示一个字典或者列表中的某个元素:
{ {your_dict[‘key’]}}
{ {your_list[0]}}
{% if user %}
{ { user }}
{% else %}
hello!
{% for index in indexs %}
{ { index }}
{% endfor %}
过滤器的本质就是函数。有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化、运算等等,而在模板中是不能直接调用 Python 中的某些方法,那么这就用到了过滤器。
使用方式:
过滤器的使用方式为:变量名 | 过滤器。
{ {variable | filter_name(*args)}}
如果没有任何参数传给过滤器,则可以把括号省略掉
{ {variable | filter_name}}
如:``,这个过滤器的作用:把变量variable 的值的首字母转换为大写,其他字母转换为小写
在 jinja2 中,过滤器是可以支持链式调用的,示例如下:
{ { “hello world” | reverse | upper }}
字符串操作
safe:禁用转义
{ { 'hello' | safe }}
capitalize:把变量值的首字母转成大写,其余字母转小写
{ { 'hello' | capitalize }}
lower:把值转成小写
{ { 'HELLO' | lower }}
upper:把值转成大写
{ { 'hello' | upper }}
title:把值中的每个单词的首字母都转成大写
{ { 'hello' | title }}
reverse:字符串反转
{ { 'olleh' | reverse }}
format:格式化输出
{ { '%s is %d' | format('name',17) }}
striptags:渲染之前把值中所有的HTML标签都删掉
{ { 'hello' | striptags }}
truncate: 字符串截断
{ { 'hello every one' | truncate(9)}}
列表操作
first:取第一个元素
{ { [1,2,3,4,5,6] | first }}
last:取最后一个元素
{ { [1,2,3,4,5,6] | last }}
length:获取列表长度
{ { [1,2,3,4,5,6] | length }}
sum:列表求和
{ { [1,2,3,4,5,6] | sum }}
sort:列表排序
{ { [6,2,3,1,5,4] | sort }}
语句块过滤
{% filter upper %}
一大堆文字
{% endfilter %}
web表单是web应用程序的基本功能。
它是HTML页面中负责数据采集的部件。表单有三个部分组成:表单标签、表单域、表单按钮。表单允许用户输入数据,负责HTML页面数据采集,通过表单将用户输入的数据提交给服务器。
在Flask中,为了处理web表单,我们一般使用Flask-WTF扩展,它封装了WTForms,并且它有验证表单数据的功能
字段对象 | 说明 |
---|---|
StringField | 文本字段 |
TextAreaField | 多行文本字段 |
PasswordField | 密码文本字段 |
HiddenField | 隐藏文件字段 |
DateField | 文本字段,值为 datetime.date 文本格式 |
DateTimeField | 文本字段,值为 datetime.datetime 文本格式 |
IntegerField | 文本字段,值为整数 |
DecimalField | 文本字段,值为decimal.Decimal |
FloatField | 文本字段,值为浮点数 |
BooleanField | 复选框,值为True 和 False |
RadioField | 一组单选框 |
SelectField | 下拉列表 |
SelectMutipleField | 下拉列表,可选择多个值 |
FileField | 文件上传字段 |
SubmitField | 表单提交按钮 |
FormField | 把表单作为字段嵌入另一个表单 |
FieldList | 一组指定类型的字段 |
验证函数 | 说明 |
---|---|
DataRequired | 确保字段中有数据 |
EqualTo | 比较两个字段的值,常用于比较两次密码输入 |
Length | 验证输入的字符串长度 |
NumberRange | 验证输入的值在数字范围内 |
URL | 验证URL |
AnyOf | 验证输入值在可选列表中 |
NoneOf | 验证输入值不在可选列表中 |
使用Flask-WTF需要配置参数SECRET_KEY。
CSRF_ENABLED是为了CSRF(跨站请求伪造)保护。 SECRET_KEY用来生成加密令牌,当CSRF激活的时候,该设置会根据设置的密匙生成加密令牌。在HTML页面中直接写form表单:
<form method="post">
<label>用户名:</label><input type="text" name="username"><br>
<label>密码:</label><input type="password" name="password"><br>
<label>确认密码:</label><input type="password" name="password2"><br>
<input type="submit" value="提交"><br>
{
% for message in get_flashed_messages() %}
{
{
message }}
{
% endfor %}
</form>
视图函数中获取表单数据:
'''
目的: 实现一个简单的登录的逻辑处理
1. 路由需要有get和post两种请求方式 --> 需要判断请求方式
2. 获取请求的参数
3. 判断参数是否填写 & 密码是否相同
4. 如果判断都没有问题, 就返回一个success
'''
app = Flask(__name__)
'''
给模板传递消息
flash --> 需要对内容加密. 因此需要设置secret_key, 做加密消息的混淆
模板中需要遍历消息
'''
app.secret_key = 'itheima'
from flask import Flask,render_template,request
app.secret_key = 'heima'
@app.route('/', methods=['GET', 'POST'])
def hello_world():
# 1. 判断请求方式是post
if request.method == 'POST':
# 2. 获取参数, 并效验参数完整性, 如果有问题就进行flash
username = request.form.get('username')
password = request.form.get('password')
password2 = request.form.get('password2')
if not all([username, password, password2]):
flash('params error')
# 3. 效验密码
elif password != password2:
flash('password error')
# 4. 没有问题就返回'success'
else:
print username
return 'success'
return render_template('wtf.html')
@app.route('/', methods=['GET', 'POST'])
def index():
# request: 请求对象 --> 获取请求方式、数据
# 1. 判断请求方式
if request.method == 'POST':
# 2. 获取请求的参数
username = request.form.get('username')
password = request.form.get('password')
password2 = request.form.get('password2')
print (password)
# 3. 判断参数是否填写 & 密码是否相同
if not all([username, password, password2]):
# print '参数不完整'
flash('参数不完整')
elif password != password2:
# print '密码不一致'
flash('密码不一致')
else:
return 'success'
return render_template('wtf.html')
if __name__ == '__main__':
app.run(debug=True)
模板页面:
<form method="post">
{
{
form.csrf_token() }}
{
{
form.username.label }}{
{
form.username }} <br>
{
{
form.password.label }}{
{
form.password }} <br>
{
{
form.password2.label }}{
{
form.password2 }} <br>
{
{
form.submit}} <br>
</form>
视图函数:
'''
使用WTF实现表单
自定义表单类
'''
class LoginForm(FlaskForm):
username = StringField('用户名:', validators=[DataRequired()])
password = PasswordField('密码:', validators=[DataRequired()])
password2 = PasswordField('确认密码:', validators=[DataRequired(), EqualTo('password', '密码填入的不一致')])
submit = SubmitField('提交')
@app.route('/form', methods=['GET', 'POST'])
def login():
login_form = LoginForm()
# 1. 判断请求方式
if request.method == 'POST':
# 2. 获取请求的参数
username = request.form.get('username')
password = request.form.get('password')
password2 = request.form.get('password2')
# 3. 验证参数. WTF可以一句话就实现所有的校验
# 我们没有CSRF token
if login_form.validate_on_submit():
print (username, password)
return 'success'
else:
flash('参数有误')
return render_template('wtf.html', form=login_form)