Flask 学习(二)jinja2模板介绍
控制语句和表达式
举例
Flask Python代码
from flask import Flask, render_template, redirect, request
app = Flask(__name__)
STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'}
STUDENT_LIST = [
    {'name': 'Old', 'age': 38, 'gender': '中'},
    {'name': 'Boy', 'age': 73, 'gender': '男'},
    {'name': 'EDU', 'age': 84, 'gender': '女'}
]
STUDENT_DICT = {
    'a': {'name': 'Old', 'age': 38, 'gender': '中'},
    'b': {'name': 'Boy', 'age': 73, 'gender': '男'},
    'c': {'name': 'EDU', 'age': 84, 'gender': '女'},
}
@app.route("/detail")
def detail():
    print(url_for("detail"))
    return render_template("detail.html", **STUDENT)
@app.route("/detail_list", )
def detail_list():
    return render_template("detail_list.html", stu_list=STUDENT_LIST)
@app.route("/detail_dict")
def detail_dict():
    return render_template("detail_dict.html", stu_dict=STUDENT_DICT)
detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title> </head>
<body>
{{ stu }}
<table border="1px">
<tr>
<td>name</td>
<td>age</td>
<td>gender</td>
</tr>
<tr>
<td>{{ name }}</td>
<td>{{ age }}</td>
<td>{{ gender }}</td>
</tr>
</table>
</body>
</html>
detail_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title> </head>
<body>
{{ stu_list }}
<table border="1px">
<tr>
<td>name</td>
<td>age</td>
<td>gender</td>
</tr>
{% for stu in stu_list %}
{% if stu.name != "Old" %}
{% if stu.age != 73 %}
<tr>
<td>{{ stu.name }}</td>
<td>{{ stu.get("age") }}</td>
<td>{{ stu["gender"] }}</td>
</tr>
{% endif %}
{% endif %}
{% endfor %}
</table>
</body>
</html>
detail_dict.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title> </head>
<body>
{{ stu_dict }}
<table border="1px">
<tr>
<td>id</td>
<td>name</td>
<td>age</td>
<td>gender</td>
</tr>
{% for stu_key,stu_value in stu_dict.items() %}
<tr>
<td>{{ stu_key }}</td>
<td>{{ stu_value.get("name") }}</td>
<td>{{ stu_value.age }}</td>
<td>{{ stu_value.gender }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
表达式
1.最常用的是变量,由Flask渲染模板时传过来,比如name
也可以是任意一种Python基础类型,比如字符串{{stu_list}},用引号括起;或者数值,列表,元祖,字典,布尔值。直接显示基础类型没啥意义,一般配合其他表达式一起用
2.运算。包括算数运算,如{{ 2 + 3 }};比较运算,如{{ 2 > 1 }};逻辑运算,如{{ False and True }}
3.过滤器|和测试器is
4.函数调用,如{{ current_time() }};数组下标操作,如{{ arr[1] }}
in操作符,如{{ 1 in [1,2,3] }}
5.字符串连接符~,作用同Python中的+一样,如{{ "Hello " ~ name ~ "!" }}
6.None值处理{{name or ""}
控制语句
Jinja2的控制语句主要就是条件控制语句if,和循环控制语句for,语法类似于Python
if-else:
{% if name and name == 'admin' %}
<h1>This is admin console</h1>
{% elif name %}
<h1>Welcome {{ name }}!</h1>
{% else %}
<h1>Please login</h1>
{% endif %} for:
{% for stu in stu_list%}
{{ stu }}
{% endfor %}
过滤器
字符串
<body>
{# 当变量未定义时,显示默认字符串,可以缩写为d #}
<p>{{ name | default('No name', true) }}</p> {# 单词首字母大写 #}
<p>{{ 'hello world' | capitalize }}</p> {# 单词全小写 #}
<p>{{ 'XML' | lower }}</p> {# 去除字符串前后的空白字符 #}
<p>{{ ' hello ' | trim }}</p> {# 字符串反转,返回"olleh" #}
<p>{{ 'hello' | reverse }}</p> {# 格式化输出,返回"Number is 99" #}
<p>{{ '%s is %d' | format("Number", 99) }}</p> {# 关闭HTML自动转义 #}
<p>{{ '<em>name</em>' | safe }}</p> {% autoescape false %}
{# HTML转义,即使autoescape关了也转义,可以缩写为e #}
<p>{{ '<em>name</em>' | escape }}</p>
{% endautoescape %} </body>
数值操作
{# 四舍五入取整,返回13.0 #}
<p>{{ 12.98 | round }}</p>
{# 向下截取到小数点后2位,返回12.88 #}
<p>{{ 12.8888 | round(2, 'floor') }}</p>
{# 绝对值,返回12 #}
<p>{{ -12 | abs }}</p>
列表操作
# 取第一个元素 #}
<p>{{ [1,2,3] | first }}</p> {# 取最后一个元素 #}
<p>{{ [1,2,3] | last }}</p> {# 返回列表长度,可以写为count #}
<p>{{ [1,2,3,4,5] | length }}</p> {# 列表求和 #}
<p>{{ [1,2,3,4,5] | sum }}</p> {# 列表排序,默认为升序 #}
<p>{{ [3,2,1,5,4] | sort }}</p> {# 合并为字符串,返回"1 | 2 | 3 | 4 | 5" #}
<p>{{ [1,2,3,4,5] | join(' | ') }}</p> {# 列表中所有元素都全大写。这里可以用upper,lower,但capitalize无效 #}
<p>{{ ['alex','bob','ada'] | upper }}</p>
字典
{% set users=[{'name':'Tom','gender':'M','age':20},
              {'name':'John','gender':'M','age':18},
              {'name':'Mary','gender':'F','age':24},
              {'name':'Bob','gender':'M','age':31},
              {'name':'Lisa','gender':'F','age':19}]
%}
{# 按指定字段排序,这里设reverse为true使其按降序排 #}
<ul>
{% for user in users | sort(attribute='age', reverse=true) %}
     <li>{{ user.name }}, {{ user.age }}</li>
{% endfor %}
</ul>
{# 列表分组,每组是一个子列表,组名就是分组项的值 #}
<ul>
{% for group in users|groupby('gender') %}
    <li>{{ group.grouper }}<ul>
    {% for user in group.list %}
        <li>{{ user.name }}</li>
    {% endfor %}</ul></li>
{% endfor %}
</ul>
{# 取字典中的某一项组成列表,再将其连接起来 #}
<p>{{ users | map(attribute='name') | join(', ') }}</p>

自定义过滤器
# 第一种方式
def get_even_list(l):
return l[::2]
# 函数的第一个参数是过滤器函数,第二个参数是过滤器名称
app.add_template_filter(get_even_list, 'even_filter') # 第二种方式
@app.template_filter() # 过滤器函数
def is_even(num):
if num % 2 == 0:
return "even number"
else:
return "odd number"
使用
<p>{{ [1,2,3,4,5] | even_filter }}</p>
<p>{{ 2 | is_even }}</p>
测试器
测试器总是返回一个布尔值,它可以用来测试一个变量或者表达式,使用”is”关键字来进行测试。
 {% set name='ab'  %}
{% if name is lower %}
  <h2>"{{ name }}" are all lower case.</h2>
{% endif %}
测试器本质上也是一个函数,它的第一个参数就是待测试的变量,在模板中使用时可以省略去。如果它有第二个参数,
模板中就必须传进去。测试器函数返回的必须是一个布尔值,这样才可以用来给if语句作判断。
内置测试器
举例
{# 检查变量是否被定义,也可以用undefined检查是否未被定义 #}
{% if name is defined %}
    <p>Name is: {{ name }}</p>
{% endif %}
{# 检查是否所有字符都是大写 #}
{% if name is upper %}
  <h2>"{{ name }}" are all upper case.</h2>
{% endif %}
{# 检查变量是否为空 #}
{% if name is none %}
  <h2>Variable is none.</h2>
{% endif %}
{# 检查变量是否为字符串,也可以用number检查是否为数值 #}
{% if name is string %}
  <h2>{{ name }} is a string.</h2>
{% endif %}
{# 检查数值是否是偶数,也可以用odd检查是否为奇数 #}
{% if 2 is even %}
  <h2>Variable is an even number.</h2>
{% endif %}
{# 检查变量是否可被迭代循环,也可以用sequence检查是否是序列 #}
{% if [1,2,3] is iterable %}
  <h2>Variable is iterable.</h2>
{% endif %}
{# 检查变量是否是字典 #}
{% if {'name':'test'} is mapping %}
  <h2>Variable is dict.</h2>
{% endif %}
官方文档
https://jinja.palletsprojects.com/en/master/templates/#builtin-tests
自定义测试器
定义
# 自定义测试器
# 第一种方式
import re
def test_tel(tel_num):
tel_re = r'\d{11}'
return re.match(tel_re,tel_num) app.add_template_test(test_tel,"is_tel") # 第二种方式
@app.template_test('start_with')
def start_with(str, suffix):
return str.lower().startswith(suffix.lower())
使用
{% set tel = '' %}
{% if tel is is_tel %}
  <h2>{{ tel }} is mobile phone</h2>
{% endif %}
 {% set name = 'Hello world' %}
{% if name is start_with 'hello' %}
  <h2>"{{ name }}" start_with "hello"</h2>
{% endif %}
全局函数
内置全局函数
{# 全局函数range()的作用同Python里的一样,返回指定范围内的数值序列。三个参数分别是开始值,结束值(不包含),间隔。
如果只传两个参数,那间隔默认为1;如果只传1个参数,那开始值默认为0。 #}
<ul>
 {% for num in range(10,20,2) %}
  <li>Number is "{{ num }}"</li>
{% endfor %}
</ul>
{# dict()函数,方便生成字典型变量 #}
{% set user = dict(name='Joh',age=22) %}
<p>{{ user | tojson | safe }}</p>
{# 显示 '{"age": 22, "name": "Joh"}' #}
{# joiner()函数,它可以初始化为一个分隔符,然后第一次调用时返回空字符串,以后再调用则返回分隔符 #}
{% set sep = joiner("|") %}
{% for val in range(5) %}
    {{ sep() }} <span>{{ val }}</span>
{% endfor %}
{# 显示 "0 | 1 | 2 | 3 | 4" #}
{# cycler()函数,在给定的序列中轮循 #}
{% set cycle = cycler('odd', 'even') %}
<ul>
{% for num in range(10, 20, 2) %}
    <li class="{{ cycle.next() }}">Number is "{{ num }}",
    next line is "{{ cycle.current }}" line.</li>
{% endfor %}
{#
next(),返回当前值,并往下一个值轮循
reset(),重置为第一个值
current,当前轮循到的值
#}
</ul>
官方文档
https://jinja.palletsprojects.com/en/master/templates/#list-of-global-functions
自定义全局函数
定义
# 自定义全局函数
# 第一种方式 @app.template_global()
def add_sum(*args):
return sum(args) # 第二种方式
import time
def current_time(timeFormat="%b %d, %Y - %H:%M:%S"):
return time.strftime(timeFormat) app.add_template_global(current_time, 'current_time')
使用
<p>{{ add_sum(1,2,3,4,5) }}</p>
<p>Current Time is: {{ current_time() }}</p>
<p>Current Day is: {{ current_time("%Y-%m-%d") }}</p>
块 (Block)
一般我们的网站虽然页面多,但是很多部分是重用的,比如页首,页脚,导航栏之类的。对于每个页面,都要写这些代码,很麻烦。
Flask的Jinja2模板支持模板继承功能,省去了这些重复代码。
template:
<body>
你好,template1
{% block template1 %} {% endblock %}
你好,template2
{% block template2 %} {% endblock %}
你好,template
{% block template %} {% endblock %}
</body>
extend:
{% extends "he.html" %}
{% block template %}
    <h1>yuan</h1>
{% endblock %}
{% block template1 %}
    <h1>alex</h1>
{% endblock %}
{% block template2 %}
    <h1>wu</h1>
    {% include "aaa.html" %}
{% endblock %}
Flask 学习(二)jinja2模板介绍的更多相关文章
- Python Flask学习笔记之模板
		Python Flask学习笔记之模板 Jinja2模板引擎 默认情况下,Flask在程序文件夹中的templates子文件夹中寻找模板.Flask提供的render_template函数把Jinja ... 
- Python框架学习之Flask中的Jinja2模板
		前面也提到过在Flask中最核心的两个组件是Werkzeug和Jinja2模板.其中Werkzeug在前一节已经详细说明了.现在这一节主要是来谈谈Jinja2模板. 一.为什么需要引入模板: 在进行软 ... 
- Flask初学者:Jinja2模板
		Python的Jinja2模板,其实就是在HTML文档中使用控制语句和表达语句替换HTML文档中的变量来控制HTML的显示格式,Python的Jinja2模板可以更加灵活和方便的控制HTML的显示,而 ... 
- flask 学习(二)
		安装了flask扩展 以及flask-bootstrap 默认情况下,flask在template文件夹寻找模板. flask 加载的是Jinja2模板,该模板引擎在flask中由函数render_t ... 
- Flask 框架下 Jinja2 模板引擎高层 API 类——Environment
		Environment 类版本: 本文所描述的 Environment 类对应于 Jinja2-2.7 版本. Environment 类功能: Environment 是 Jinja2 中的一个 ... 
- web开发框架Flask学习二
		jinja2模板规范 在当前项目中创建一个文件为templates的文件夹,将其设置为模板文件夹,新建的html为模板页面, 在视图函数中使用render_template(".html的文 ... 
- 测开之路二十九:Flask基础之jinja2模板
		中文文档:http://docs.jinkan.org/docs/jinja2/ 与静态资源一样,Flask默认的模板目录名为templates,如果有需要的话和static一样,要在初始化的时候声明 ... 
- Flask学习 二 模板
		jinja2模版 from flask import Flask,render_template app = Flask (__name__) @app.route ('/<name>') ... 
- flask学习(九):模板渲染和参数传递
		一. 如何渲染模板 1. 模板放在templates文件夹下 2. 从flask中导入render_template函数 3. 在视图函数中,使用render_template函数,渲染模板 注意:只 ... 
随机推荐
- C++学习(6)—— 引用
			1. 引用的基本使用 作用:给变量起别名 语法:数据类型 &别名 = 原名 #include<iostream> using namespace std; int main(){ ... 
- 100% 成功率的 offer 收割机是怎样练成的?
			都说今年的形势不好,各种找工作不顺利,但我身边就有一位同学,每次面试都拿到offer,我特意邀请他来给大家分享下经验,虽然不同人的技术领域未必相同,但很多东西是相通的,希望本文能对大家有所帮助. 下面 ... 
- font-awesome图标显示问题解决方案
			font-awesome一个很强大的字体图标库.下载链接:http://fontawesome.dashgame.com/刚开始使用font-awesome的新手往往容易只引入一个css文件,这样就会 ... 
- 项目Beta冲刺(团队7/7)
			项目Beta冲刺(团队) --7/7 作业要求: 项目Beta冲刺(团队) 1.团队信息 团队名 :男上加男 成员信息 : 队员学号 队员姓名 个人博客地址 备注 221600427 Alicesft ... 
- Codeforces 484 E. Sign on Fence
			[传送门] 题意就是给一排围栏,每个围栏都有一个高度,查询区间$\left[l, r\right]$之间长度为$w$的子区间的最小高度的最大值.首先,这个最大值肯定是这个区间里的围栏的某个高度,如果是 ... 
- 拓展-教你手把手用纯CSS写轮播图
			先看成品图[示例网址:][1] [1]: https://huruji.github.io/css-imitate-js/slider/index.html一.随便说几句####css3动画效果的强大 ... 
- Linux yum 包 下载地址
			yum包网址: http://www.rpmfind.net/linux/rpm2html/search.php?query=yum 
- Visual Studio 调试技巧---指针,元素个数
			刚才,我在Visual Studio 中发现了一个以更好的方式调试指针的技巧.您可以在监视窗口中选择“n”,其中“n”是要显示的元素数.我认为下图是不言而喻的. 
- 在调试时,有什么更好的方法可以监视最后一个win32错误?
			我发现在代码中使用win32api时,需要多次监视最后一个win32错误!(在每次使用API后调用GetLastError()是不可行的解决方案!).. 在Visual Studio中,它们提供了一个 ... 
- 【CF55D】Beautiful numbers
			[CF55D]Beautiful numbers 题面 洛谷 题解 考虑到如果一个数整除所有数那么可以整除他们的\(lcm\),而如果数\(x\)满足\(x\bmod Lcm(1,2...,9)=r\ ... 
