flask模板语言
由于Django的模板引擎和Flask中的Jinja2模板引擎有很多一样的地方,所以我将一样的地方总结到了独立的文章中
https://www.cnblogs.com/kuxingseng95/articles/9091027.html
变量
构造上下文
构造上下文前
return render_template('test01_template.html', my_list=my_list, my_int=my_int, my_dict=my_dict)
构造上下文后
return render_template('test01_template.html', context=context)
return render_template('test01_template.html', **context)
比如:
from flask import Flask, render_template app = Flask(__name__) @app.route("/index") def index(): # 处理业务逻辑 data = { "name": "python", "age": 18, "my_li": [1, 2, 3, 4, 5, 6, 7], "my_int": 0, "my_dict": { "city": "bj" } } return render_template("code_18_templates.html", **data) if __name__ == '__main__': app.run(debug=True)
和Django不同,在Flask的Jinja2模板引擎中,{{变量}}中是支持计算的
过滤器
jinja2中过滤器可以传入多个参数。
{{参数1 | 过滤器器(*args) }}
{{ my_list2 | sum(‘age’) }}
而且支持链式调用
{{ 'hello world' | reverse | upper }}
自定义过滤器
使用装饰器
from flask import Flask, render_template app = Flask(__name__) @app.route("/") def index(): return render_template("code_19_filter.html") # 自定义过滤器 # 定义一个切片函数 @app.template_filter("li2") # 里面的参数表示过滤器的名字 def li_setup2(li): # 每隔一个值获取一下 step = li[::2] return step if __name__ == '__main__': app.run()
直接添加到模板过滤器中
from flask import Flask, render_template app = Flask(__name__) @app.route("/") def index(): return render_template("code_19_filter.html") # 定义一个切片函数 def li_setup2(li): # 每隔一个值获取一下 return li[::2] # 自定义过滤器 # 第一个参数:表示自定义的函数名字, # 第二个参数表示过滤器的名字 app.add_template_filter(li_setup2, "li2") if __name__ == '__main__': app.run()
控制语句
与Django模板不同点
for循环后面可以拼接if语句
比较平时使用时我们需要这样:
{% for index in my_list %}
{% if index > 5 %}
{{ index }}
{% endif %}
{% endfor %}
而Flask中可以这样:
{% for index in my_list if index > 5 %}
{{index}}
{% endfor %}
比如在判断列表为空的时候
Django和jinja2也不一样
jinja2中
{% for index in my_list %}
{{index}}
{% else %}
没有值了
{% endfor %}
django中
{% for index in my_list %}
{{index}}
{% empty %}
没有值了
{% endfor %}
宏
可以将它看成时Jinja2中的一个函数,它会返回一个模板或者HTML字符串
可以将相同的重复编写的模板代码封装到宏中
使用
标签
{% macro func() %}
{% endmacro %}
准备宏
{% macro input(label='', type='text', name='', value='') %}
<label>{{ label }}</label><input type="{{ type }}" name="{{ name }}" value="{{ value }}"><br>
{% endmacro %}
使用宏
<form action=""> {{ input(label='⽤用户名:', name='user_name') }} {{ input(label='邮箱:', name='email') }} {{ input(label='密码:', type='password', name='password') }} {{ input(label='确认密码:', type='password', name='password2') }} {{ input(type='submit', value='提交') }} </form>
封装宏
为了达到宏的复用,我们可以将宏单独的抽取到指定的html文件中
使用封装的宏
{% import 'macro.html' as func %}
<form action="">
{{ func.input(label='⽤用户名:', name='user_name') }}
{{ func.input(label='邮箱:', name='email') }}
{{ func.input(label='密码:', type='password', name='password') }}
{{ func.input(label='确认密码:', type='password', name='password2') }}
{{ func.input(type='submit', value='提交') }}
</form>
Flask中特有的模板变量和方法
特有变量
比如:

特有变量:
request:获取请求的数据
session:获取session数据
config:获取配置参数
g:获取视图中g变量存储的值
特有方法
url_for()
@app.route("/order/<order_id>") def order(order_id): return 'order %s' % order_id
超链接中的反向解析,和重定向中的反向解析用法一致
比如在视图函数中定义了
@app.route('/order') def order(): return "order"
然后再模板中
<a href="{{ url_for('order') }}">进⼊入order</a>
可以进行反向的解析
反向的解析传参
@app.route("/order/<order_id>") def order(order_id): return "order %s" % order_id
<a href="{{ url_for('order', order_id=123) }}">进⼊入order</a>
get_flashed_messages()
搭配flask中国的flash()方法使用
flash()用于将视图中准备的提示信息添加到消息队列中
然后模板中使用get_flashed_messages()提取和展示视图中准备的提示信息
使用
{% for message in get_flashed_messages() %}
{{message}}
{% endfor %}
Flask-WTF表单
首先需要安装 Flask-WTF == 0.14.2
常用模块
表单类
from flask_wtf import FlaskForm
字段
from wtforms import StringField, PasswordField, SubmitField
验证器
from wtforms.validators import DataRequired, InputRequired, EqualTo
例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post"> {{ form.csrf_token }} {{ form.user_name.label }} <p>{{ form.user_name }}</p> {% for msg in form.user_name.errors %} <p>{{ msg }}</p> {% endfor %} {{ form.password.label }} <p>{{ form.password }}</p> {% for msg in form.password.errors %} <p>{{ msg }}</p> {% endfor %} {{ form.password2.label }} <p>{{ form.password2 }}</p> {% for msg in form.password2.errors %} <p>{{ msg }}</p> {% endfor %} {{ form.submit }} </form> </body> </html>
from flask import Flask, render_template from flask import request from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SubmitField from wtforms.validators import DataRequired, EqualTo app = Flask(__name__) class Config(object): SECRET_KEY = "fadafsfafsafa" app.config.from_object(Config) # FlaskForm:继承flask的表单 class RegisterForm(FlaskForm): # StringField :文本输入框 # validators :用来验证当前的文本输入框 # DataRequired:必须输入 user_name = StringField(label="用户名", validators=[DataRequired("必须填写用户名")]) password = PasswordField(label="密码", validators=[DataRequired("必须填写密码")]) # EqualTo : 判断两次密码是否相等 # password : 表示跟上面的密码进行判断,判断两次是否一致 password2 = PasswordField(label="确认密码", validators=[DataRequired("必须填写密码"), EqualTo("password", "两次密码必须一致")]) submit = SubmitField(label="提交") @app.route("/register", methods=["GET", "POST"]) def register(): if request.method == "GET": form = RegisterForm() return render_template("code_22_wtf.html", form=form) else: form = RegisterForm() if form.validate_on_submit(): name = form.user_name.data pwd = form.password.data pwd2 = form.password2.data print(name, pwd) return "注册成功" else: return render_template("code_22_wtf.html", form=form) if __name__ == '__main__': app.run(debug=True)
关于csrf
关于csrf的简单介绍:https://www.cnblogs.com/kuxingseng95/articles/9092333.html
防护措施
方案一:在FlaskForm中实现校验
在Flask-WTF扩展中,有一套完整的csrf防护体系
<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 }} </form>
方案二:单独使用
from flask.ext.wtf import CSRFPRrotect
CSRFProtect(app)
使用WTF拓展
同方案一
不使用WTF拓展
自己实现校验的所有逻辑
<form method="post" action="/"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>

浙公网安备 33010602011771号