Flask中的Jinja2简单用法
在Python中,该漏洞常见于Flask(一个轻量级Web应用框架)模块中,Flask使用Jinja2作为模板引擎
模板
-
{{...}}
:将花括号内的内容作为表达式执行并返回对应结果。1
2# 会被解析为49
{{7*7}} -
{%...%}
:用于声明变量或条件/循环语句1
2
3
4
5
6# 使用set声明变量
{% set name='ikun' %}
# 条件语句
{% if var is true %}ikun{%endif%}
# 循环语句
{% for i in range(6) %}ikun{%endfor%} -
``:注释
变量
全局变量
使用set语句
1 | {% set name='ikun' %} |
之后就可以在页面文件中使用name这个变量了
局部变量
使用with语句来创建一个内部作用域
1 | {% with name='ikun' %} |
name变量只能在with标签中使用
控制语句
控制语句都是放在{% ... %}
中,并且有一个语句{% endxxx %}
来进行结束
if语句
1 | {% if user.is_admin %} |
for语句
普通用法
1 | <u1> |
遍历字典
1 | {% for key,value in my_dict.items() %} |
循环变量loop
1 | {% for item in items %} |
运算符
+
号运算符:数字相加,字符串相加,列表相加。但是并不推荐使用+
运算符来操作字符串,字符串相加应该使用~
运算符。-
号运算符:只能对两个数字相减。/
号运算符:对两个数进行相除。%
号运算符:取余运算。*
号运算符:乘号运算符,并且可以对字符进行相乘。**
号运算符:次幂运算符,比如2**3=8。in
操作符:跟python中的in
一样使用,比如{{1 in [1,2,3]}}
返回true
。~
号运算符:拼接多个字符串,比如{{"Hello" ~ "World"}}
将返回HelloWorld
宏(非常重要)
宏是 Jinja2 中的一种可重用代码块,类似于其他编程语言中的函数
宏相当于一个搭建好的页面一部分,可以被引入,可以往宏传递参数。可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出来当成一个变量,在使用宏时传递参数,从而将宏渲染成为页面的一部分
定义和调用宏
1 | {# 定义宏 #} |
如定义和调用一个input标签宏
1 | {% macro inpput(name,value='',type='text',class='') %} |
页面文件中导入宏(import)
在开发中,会将一些常用的宏单独放在一个文件中,需要时再从这个文件中导入
py中import解析
1.直接导入整个模块
1 import math2.导入模板并设置别名
1 import numpy as np3.导入特定函数/类
1 from math import sqrt,pi4.导入并设置别名
1 from datetime import datetime as dt
1 | {% import 'forms.html' as forms %} //导入宏文件 |
导入模板并不会把当前上下文中的变量添加到被导入的模板中,我们可以在导入的时候使用with context 把上下文传进去:
1 | {% from 'forms.html' import my_macro with context %} |
宏文件中引用其他宏(include)
include
语句可以把一个模板引入到另外一个模板中,类似于把一个模板的代码copy到另外一个模板的指定位置
1 | {# greeting.html #} |
模板文件的继承
模板允许构建一个基础"骨架"模板,然后让子模板继承并覆盖特定部分
基础模板(base.html):
1 | <!DOCTYPE html> |
子模板(child.html):
1 | {% extends "base.html" %} |
{% extends %}
指令
- 必须是模板的第一个标签
- 指定要继承的父模板路径
- 子模板中未定义的块将使用父模板的默认内容
{% block %}` 标签 - 定义可被覆盖的内容区块 - 基本语法:`{% block block_name %}内容{% endblock %}
- 支持嵌套 block
{{ super() }}
函数
- 在子模板中调用父模板的 block 内容
- 可以控制父模板内容的插入位置
模板文件中对block内容的调用,可以使用 self.blockName
的方式
1 | <title>{% block title %}{% endblock %}</title> |
过滤器
过滤器是通过(|
)符号进行使用的,其相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中
分类 | 过滤器 | 功能描述 | 使用示例 | 输出结果 |
---|---|---|---|---|
字符串处理 | lower |
转换为小写 | {{ "HELLO" | lower }} |
"hello" |
upper |
转换为大写 | {{ "hello" | upper }} |
"HELLO" |
|
capitalize |
首字母大写 | {{ "hello" | capitalize }} |
"Hello" |
|
trim |
去除首尾空格 | {{ " hello " | trim }} |
"hello" |
|
replace(old, new) |
字符串替换 | {{ "Hi Tom" | replace("Tom", "Alice") }} |
"Hi Alice" |
|
truncate(length=255) |
截断字符串 | {{ "Long text" | truncate(4) }} |
"Long..." |
|
列表/字典 | first |
获取第一个元素 | {{ [1,2,3] | first }} |
1 |
last |
获取最后一个元素 | {{ [1,2,3] | last }} |
3 |
|
length |
获取元素数量 | {{ "hello" | length }} |
5 |
|
join(delimiter) |
连接列表元素 | {{ ["A","B"] | join("--") }} |
"A--B" |
|
sort |
排序列表 | {{ [3,1,2] | sort }} |
[1,2,3] |
|
map(attribute) |
提取对象属性 | {{ users | map(attribute='name') }} |
用户名列表 | |
数值处理 | round(precision) |
四舍五入 | {{ 3.14159 | round(2) }} |
3.14 |
abs |
绝对值 | {{ -5 | abs }} |
5 |
|
int / float |
类型转换 | {{ "3.14" | float }} |
3.14 |
|
日期时间 | datetimeformat(format) |
格式化日期 | {{ now | datetimeformat("%Y/%m/%d") }} |
"2023/08/15" |
date |
提取日期部分 | {{ now | date }} |
"2023-08-15" |
|
逻辑处理 | default(value) |
设置默认值 | {{ name | default("匿名") }} |
变量为空时输出"匿名" |
selectattr(condition) |
条件筛选列表 | {{ users | selectattr("is_active") }} |
活跃用户列表 | |
rejectattr(condition) |
反向筛选列表 | {{ users | rejectattr("is_banned") }} |
非封禁用户列表 | |
HTML安全 | escape / e |
HTML转义(防XSS) | {{ "
|