Falsk Jinja2模板
使用步骤
在 应用 同级目录下创建模板文件夹 templates . 文件夹名称固定写法.
在 templates 文件夹下, 创建 应用 同名文件夹. 例, Book
在 应用 同名文件夹下创建 网页模板 文件. 例 : index.html
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/test')
def index():
return render_template('index.html')
模板传参
关键字传参
变量: {{ uname}}
字典等复杂数据,获取方式是: {{childrens.name}} 或者 {{childrens[‘name’]}}
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return
render_template('index.html',uname='Test')
<body>
从模版中渲染的数据
<br>
{{ uname}}
</body>
模板使用url_for函数
无论是 路径参数 还是 查询式参数 都可以直接传递
app.route('/accounts/login/<name>/')
def login(name):
print(name)
return '通过URL_FOR定位过来的!!!'
<a href="{{ url_for('login',p1='abc',p2='ddd',name='Test') }}">登录/a>
过滤器
自带过滤器
过滤器是通过管道符号 | 使用的,例如: { name|length }} 将返回name的长度。过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。Jinja2中内置了许多过滤器
https://jinja.palletsprojects.com/en/3.0.x/templates/#filters
默认过滤器
body>
<h1>default过滤器</h1>
过滤前的昵称数据是:{{nick_name}}<br>
过滤后的昵称数据是:{{nick_name | default('用户1',boolean=true)}}<br>
过滤后的昵称数据是:{{nick_name or '用户2'}}
<br>
</body>
转义字符
<body>
<h1>转义字符过滤器</h1>
<!-- 模板中默认 做了转义字符的效果 -->
转义前的数据是:{{ info | safe }} <!-- 不转义:不将特殊字符转换成 <类似的数据 -->
{% autoescape true %} <!-- false代表不再转义特殊字符 / true 转义特殊字符 <-->
{{info }} <!-- 转义:将特殊字符转换成 <类似的数据 -->
{% endautoescape %}
</body>
其他过滤器
jinja2模板 默认全局开启了自动转义功能safe 过滤器:可以关闭一个字符串的自动转义
escape 过滤器:对某一个字符串进行转义
autoescape 标签,可以对他包含的代码块关闭或开启自动转义
{% autoescape true/false %} 代码块 {% endautoescape %}
自定义过滤器
过滤器本质上就是一个函数。如果在模版中调用这个过滤器,那么就会将这个变量的值作为第一个参数传给过滤器这个函数,然后函数的返回值会作为这个过滤器的返回值。
需要使用到一个装饰器: @app.template_filter(‘过滤器名称’)
#将模版设置为自动加载模式
app.config['TEMPLATES_AUTO_RELOAD']=True
@app.template_filter('count')
def count(value):
value=value.replace("旧值",'新值')
return value
<p>使用自定义过滤器:{{内容值|count}}</p>
流程控制
所有的控制语句都是放在 {% … %} 中,并且有一个语句 {% endxxx %} 来进行结束!
if:if语句和python中的类似,可以使用 >,<,<=,>=,==,!= 来进行判断,也可以通过 and,or,not,() 来进行逻辑合并操作
if 条件判断语句必须放在 {% if statement %} 中间,并且还必须有结束的标签 {% endif %} 。
{% if %}
{% elseif %}
{% else %}
{% endif %}
循环控制
在 jinja2 中的 for 循环,跟 python 中的 for 循环基本上是一模一样的也是 for…in… 的形式。并且也可以遍历所有的序列以及迭代器唯一不同的是, jinja2 中的 for 循环没有 break 和 continue 语句.
for…in… for循环可以遍历任何一个序列包括列表、字典、元组。并且可以进行反向遍历,以下将用几个例子进行解释:
ul>
{% for user in users%}
<li>{{ user}}</li>
{% endfor %}
</ul>
并且Jinja中的for循环还包含以下变量,可以用来获取当前的遍历状
态:
宏的使用
模板中的宏跟python中的函数类似,可以传递参数,但是不能有返回值可以将一些经常用到的代码片段放到宏中,然后6把一些不固定的值抽取出来当成一个变量.
定义宏
{% macro input(name,value="",type="text") %}
<input type="{{type}}" name="{{name}}" value="{{value}}">
{% endmacro %}
使用宏
<table>
<tr>
<td>用户名:</td>
<td>{{ input('username')}}</td>
</tr>
<tr>
<td>密码:</td>
<td>
{{ input('pwd',type='password') }}
</td>
</tr>
<tr>
<td></td>
<td>{{ input(value='提交',type='submit') }}</td>
</tr>
</table>
导入宏
实际开发中,不会把宏在一个页面内定义 并直接使用一般把宏定义放到一个专门的文件夹中,方便进行统一管理
之后,哪一个页面需要使用某个宏,需要导入宏才能使用.
导入方式
from ‘宏文件的路径’ import 宏的名字 [as xxx]
{% from "users/users.html" import input asinp %}
import “宏文件的路径” as xxx [withcontext ]
{% import "users/users.html" as usr withcontext %}
宏文件路径,不要以相对路径去寻找,都要以 templates 作为绝对路径去找.
如果想要在导入宏的时候,就把当前模版的一些参数传给宏所在的模版,那么就应该在导入的时候使用 with contex
{% import "users/users.html" as usr withcontext %}
导入模板include
1.这个标签相当于是直接将指定的模版中的代码复制粘贴到当前位置。
2. include 标签,如果想要使用父模版中的变量,直接用就可以了,不需要使用 with context 。
3. include 的路径,也是跟 import 一样,直接从 templates 根目录下去找,不要以相对路径去找。
set与with标签
set的使用
在模版中,可以使用 set 语句来定义变量
<!--set语句来定义变量,之后,那么在后面的代码中,都可以使用这个变量-->
{% set uname='Test'%}
<p>用户名:{{ uname }}</p>
with语句
with 语句定义的变量,只能在 with 语句块中使用,超过了这个代码块,就不能再使用了
<!--with语句来定义变量,只有在指定区域 才能使用这个变量-->
{% with classroom='python202'%}
<p>班级:{{ classroom }}</p>
{% endwith %}
关于定义的变量, with 语句也不一定要跟一个变量,可以定义一个空的 with 语句,需要在指定的区域才能使用的情况,可以set与with组合使用。
{% with %}
{% set pname='李思思' %}
<p>娱乐县县长:{{ pname }}</p>
{% endwith %}
静态文件
静态文件:css文件 js文件 图片文件等文件加载静态文件使用的是 url_for 函数。然后第一个参数需要为 static ,第
二个参数需要为一个关键字参数 filename=‘路径’ 。路径查找,要以当前项目的 static 目录作为根目录.
{{ url_for("static",filename='xxx') }}
模板继承
模版继承可以把一些公用的代码单独抽取出来放到一个父模板中以后子模板直接继承就可以使用了。这样可以重复的利用代码,并且以后修改起来也比较方便。
模版继承语法
使用 extends 语句,来指明继承的父模板。父模板的路径,也是相对于 templates 文件夹下的绝对路径。
{% extends "base.html" %}
block语法
一般在父模版中,定义一些公共的代码。子模板可能要根据具体的需求实现不同的代码。
{% extends "base.html" %}
这时候父模版就应该有能力提供一个接口,让子模板来实现。从而实现具体业务需求的功能。
父模板
{% block block的名字 %}
{% endblock %}
子模板
{% block block的名字 %}
子模板中的代码
{% endblock %}
调用父模版代码block中的代码
默认情况下,子模板如果实现了父模版定义的block。那么子模板block中的代码就会覆盖掉父模板中的代码。
如果想要在子模板中仍然保持父模板中的代码,那么可以使用 {{ super() }} 来实现
调用另外一个block中的代码
如果想要在另外一个模版中使用其他模版中的代码。那么可以通过 {{self.其他block名字() }} 就可以了