Flask最强攻略 - 跟DragonFire学Flask - 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法

https://www.cnblogs.com/DragonFire/p/9259999.html

 

是时候开始写个前端了,Flask中默认的模板语言是Jinja2

现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下

首先我们要在后端定义几个字符串,用于传递到前端

复制代码

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 = {1: {'name': 'Old', 'age': 38, 'gender': '中'},2: {'name': 'Boy', 'age': 73, 'gender': '男'},3: {'name': 'EDU', 'age': 84, 'gender': '女'},
}

复制代码

但是前提我们要知道Jinja2模板中的流程控制:

I. Jinja2模板语言中的 for

{% for foo in g %}{% endfor %}

II. Jinja2模板语言中的 if

复制代码

{% if g %}{% elif g %}{% else %}{% endif %}

复制代码

接下来,我们对这几种情况分别进行传递,并在前端显示成表格

1. 使用STUDENT字典传递至前端

后端:

@app.route("/student")
def index():return render_template("student.html", student=STUDENT)

前端:

复制代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Old Boy EDU</title>
</head>
<body>
Welcome to Old Boy EDU
<div>{{ student }}</div>
<table border="1px"><tr><td>{{ student.name }}</td><td>{{ student["age"] }}</td><td>{{ student.get("gender") }}</td></tr>
</table>
</body>
</html>

复制代码

结果:

从这个例子中,可以看出来,字典传入前端Jinja2 模板语言中的取值操作, 与Python中的Dict操作极为相似,并且多了一个student.name的对象操作

 

2. STUDENT_LIST 列表传入前端Jinja2 模板的操作:

后端:

@app.route("/student_list")
def student_list():return render_template("student_list.html", student=STUDENT_LIST)

前端:

复制代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Old Boy EDU</title>
</head>
<body>
Welcome to Old Boy EDU
<div>{{ student }}</div>
<table border="1xp">{% for foo in student %}<tr><td>{{ foo }}</td><td>{{ foo.name }}</td><td>{{ foo.get("age") }}</td><td>{{ foo["gender"] }}</td></tr>{% endfor %}
</table>
</body>
</html>

复制代码

结果:

这里我们可以看出如果是需要循环遍历的话,Jinja2 给我们的方案是

    {% for foo in student %}<tr><td>{{ foo }}</td></tr>{% endfor %}

上述代码中的 foo 就是列表中的每一个字典,再使用各种取值方式取出值即可

 

3.STUDENT_DICT 大字典传入前端 Jinja2 模板

后端:

@app.route("/student_dict")
def student_dict():return render_template("student_dict.html", student=STUDENT_DICT)

前端:

复制代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Old Boy EDU</title>
</head>
<body>
Welcome to Old Boy EDU
<table>{% for foo in student %}<tr><td>{{ foo }}</td><td>{{ student.get(foo).name }}</td><td>{{ student[foo].get("age") }}</td><td>{{ student[foo]["gender"] }}</td></tr>{% endfor %}
</table>
</body>
</html>

复制代码

在遍历字典的时候,foo 其实是相当于拿出了字典中的Key

结果:

 

4.结合所有的字符串儿全部专递前端Jinja2 模板

后端:

@app.route("/allstudent")
def all_student():return render_template("all_student.html", student=STUDENT ,student_list = STUDENT_LIST,student_dict= STUDENT_DICT)

前端:

复制代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Old Boy EDU</title>
</head>
<body>
<div> _____________________________________</div>
Welcome to Old Boy EDU : student
<div>{{ student }}</div>
<table border="1px"><tr><td>{{ student.name }}</td><td>{{ student["age"] }}</td><td>{{ student.get("gender") }}</td></tr>
</table>
<div> _____________________________________</div>
Welcome to Old Boy EDU : student_list
<div>{{ student_list }}</div>
<table border="1xp">{% for foo in student_list %}<tr><td>{{ foo }}</td><td>{{ foo.name }}</td><td>{{ foo.get("age") }}</td><td>{{ foo["gender"] }}</td></tr>{% endfor %}
</table>
<div> _____________________________________</div>
Welcome to Old Boy EDU : student_dict
<div>{{ student_dict }}</div>
<table border="1xp">{% for foo in student_dict %}<tr><td>{{ foo }}</td><td>{{ student_dict.get(foo).name }}</td><td>{{ student_dict[foo].get("age") }}</td><td>{{ student_dict[foo]["gender"] }}</td></tr>{% endfor %}
</table>
</body>
</html>

复制代码

结果:

这里可以看出来,render_template中可以传递多个关键字

 

5.利用 **{}字典的方式传递参数

前端不变(标题4的前端代码)

后端:

@app.route("/allstudent")
def all_student():return render_template("all_student.html", **{"student":STUDENT ,"student_list" : STUDENT_LIST,"student_dict": STUDENT_DICT})

 

6. Jinja2 的高阶用法

Jinja2 模板语言为我们提供了很多功能接下来看一下它有什么高级的用法

6.1. safe : 此时你与HTML只差一个 safe

后端代码:

复制代码

from flask import Flask
from flask import render_templateapp = Flask(__name__)@app.route("/")
def index():tag = "<input type='text' name='user' value='DragonFire'>"return render_template("index.html",tag=tag)app.run("0.0.0.0",5000)

复制代码

前端代码:

 前端代码

如果我们直接运行代码直接访问,你会在页面看到什么呢?

似乎和我们想要结果不太一样,有两种解决方案,

第一种,从前端入手

前端代码:

 前端代码

还有一种方式是从后端入手

后端代码:

复制代码

from flask import Flask
from flask import render_template
from flask import Markup  # 导入 flask 中的 Markup 模块app = Flask(__name__)@app.route("/")
def index():tag = "<input type='text' name='user' value='DragonFire'>"markup_tag = Markup(tag)  # Markup帮助咱们在HTML的标签上做了一层封装,让Jinja2模板语言知道这是一个安全的HTML标签print(markup_tag,type(markup_tag))  # <input type='text' name='user' value='DragonFire'> <class 'markupsafe.Markup'>return render_template("index.html", tag=markup_tag)app.run("0.0.0.0", 5000, debug=True)

复制代码

两种得到的效果是一样

 

6.2 在Jinja2中执行Python函数(模板中执行函数)

首先在文件中定义一个函数

后端代码:

复制代码

from flask import Flask
from flask import render_template
from flask import Markup  # 导入 flask 中的 Markup 模块app = Flask(__name__)#定义一个函数,把它传递给前端
def a_b_sum(a,b):return a+b@app.route("/")
def index():return render_template("index.html", tag=a_b_sum)app.run("0.0.0.0", 5000, debug=True)

复制代码

前端代码:

复制代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>{{ tag }}<br>{{ tag(99,1) }}
</body>
</html>

复制代码

看到结果就是,函数加()执行得到结果

还可以定义全局函数,无需后端传递给前端,Jinja2直接就可以执行的函数

后端代码:

复制代码

from flask import Flask
from flask import render_template
from flask import Markup  # 导入 flask 中的 Markup 模块app = Flask(__name__)@app.template_global()  # 定义全局模板函数
def a_b_sum(a, b):return a + b@app.template_filter()  # 定义全局模板函数
def a_b_c_sum(a, b, c):return a + b + c@app.route("/")
def index():return render_template("index.html", tag="")app.run("0.0.0.0", 5000, debug=True)

复制代码

前端代码:

复制代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>{{ a_b_sum(99,1) }}<br>{{ 1 | a_b_c_sum(197,2) }}
</body>
</html>

复制代码

两个函数的调用方式不太一样

尤其是@app.template_filter() 它的调用方式比较特别,这是两个Flask中的特殊装饰器

 

6.3 Jinja2模板复用 block

如果我们前端页面有大量重复页面,没必要每次都写,可以使用模板复用的方式复用模板

前端代码:

index.html 文件中的内容

 index.html

login.html 文件中的内容

 login.html

home.html 文件中的内容

 home.html

后端代码:

复制代码

from flask import Flask
from flask import render_templateapp = Flask(__name__)@app.route("/login")
def login():return render_template("login.html")@app.route("/home")
def home():return render_template("home.html")app.run("0.0.0.0", 5000, debug=True)

复制代码

然后我们可以看到什么呢?

大概是这样一个效果

在这两个页面中,只有 block 中的内容发生了变化,其他的位置完全一样

 

6.4 Jinja2模板语言的模块引用 include

login.html 文件中的内容:

<form>用户名:<input type="text" name="user">密码:<input type="text" name="pwd">
</form>

index.html 文件中的内容

复制代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>Welcome OldboyEDU</h1><h2>下面的内容是不一样的</h2>{% include "login.html" %}<h2>上面的内容是不一样的,但是下面的内容是一样的</h2><h1>OldboyEDU is Good</h1>
</body>
</html>

复制代码

后端代码:

复制代码

from flask import Flask
from flask import render_templateapp = Flask(__name__)@app.route("/")
def index():return render_template("index.html")app.run("0.0.0.0", 5000, debug=True)

复制代码

看到的结果

这就是将 login.html 当成一个模块,加载到 index.html 页面中

 

6.5 Jinja2模板语言中的宏定义

前端代码:

复制代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>Welcome OldboyEDU</h1>{% macro type_text(name,type) %}<input type="{{ type }}" name="{{ name }}" value="{{ name }}">
{% endmacro %}<h2>在下方是使用宏来生成input标签</h2>{{ type_text("one","text") }}
{{ type_text("two","text") }}</body>
</html>

复制代码

宏定义一般情况下很少应用到,但是要知道有这么个概念

 

第四篇,完结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400028.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Jetson Nano学习笔记】1. 系统镜像和ROS的安装

目录安装系统换源安装VNC服务安装ROS初始化rosdep和环境测试平台&#xff1a;Jetson Nano 系统版本&#xff1a;4.6.1 安装系统 在Jetson Download Center下载镜像&#xff1a; 在树莓派资源下载 | 树莓派实验室下载工具 使用SDFormatter格式化内存卡 使用balenaEtcher烧录镜…

我的Android进阶之旅------Android利用Sensor(传感器)实现水平仪功能的小例

这里介绍的水平仪&#xff0c;指的是比较传统的气泡水平仪&#xff0c;在一个透明圆盘内充满液体&#xff0c;液体中留有一个气泡&#xff0c;当一端翘起时&#xff0c;该气泡就会浮向翘起的一端。 利用方向传感器返回的第一个参数&#xff0c;实现了一个指南针小应用。我的And…

【Jetson Nano学习笔记】2. ORB-SLAM3及ZED 2i驱动安装

目录ZED 2i驱动安装安装驱动自测ROS测试zed2i.launchrostopic listrosnode listdisplay_zed2i.launchzed_rtabmap.launchORB-SLAM3安装OpenCV 3安装Glew安装Pangolin安装boost安装Eigen 3安装OpenGL安装openssl安装ORB-SLAM3建立swap准备编译编译关闭swap平台&#xff1a;Jetso…

proj1088

滑雪Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 69608 Accepted: 25669Description Michael喜欢滑雪百这并不奇怪&#xff0c; 因为滑雪的确很刺激。可是为了获得速度&#xff0c;滑的区域必须向下倾斜&#xff0c;而且当你滑到坡底&#xff0c;你不得不再次走…

【Jetson Nano学习笔记】3. ORB-SLAM3运行双目Demo(ZED 2i)

目录修改zed-ros-wrapper的参数双目测试平台&#xff1a;Jetson Nano 系统版本&#xff1a;4.6.1 参考资料&#xff1a; zed-ros-wrapper —— ROS Wiki ZED 相机 && ORB-SLAM2安装环境配置与ROS下的调试 —— 李小铭 又一遍……ORB_SLAM2ZED相机(SDK2.2.1)CUDA9.0ROS…

MySQL数据库和ACID模型

2019独角兽企业重金招聘Python工程师标准>>> ACID模型是一组强调高可靠性的数据库系统设计原则。InnoDB存储引擎坚持ACID原则&#xff0c;确保即使在软件崩溃甚至是硬件故障的情况下&#xff0c;数据也不会损坏。当你需要依赖兼容ACID原则的业务时&#xff0c;你不必…

【Jetson Nano学习笔记】4. python 3编译bridge

目录使用python3编译boostconsole_bridgepython3bridge平台&#xff1a;Jetson Nano 系统版本&#xff1a;4.6.1 参考资料&#xff1a; How to setup ROS with Python 3 Unable to use cv_bridge with ROS Kinetic and Python3 CMake Error &#xff1a;Could not find a pac…

python time模块详解

2019独角兽企业重金招聘Python工程师标准>>> python time模块详解 分类&#xff1a; python2009-03-28 23:35 89831人阅读 评论(9) 收藏 举报 pythonstructstringdstimportdate python 的内嵌time模板翻译及说明 一、简介 time模块提供各种操作时间的函数 说明&am…

【RK3399Pro学习笔记】十九、在ROS中点亮LED灯

目录创建ROS工作空间创建ROS功能包CSysFs方式&#xff08;需root&#xff09;源文件blink.cppgpiolib.cpp头文件gpiolib.hCMakeLists.txt运行代码调用shell命令方式&#xff08;无需root&#xff09;源文件blink.cppCMakeLists.txt运行代码平台&#xff1a;华硕 Thinker Edge R…

LaTex bib引用知网论文NoteExpress格式文献 —— cnki2bib

目录先决条件安装使用最后…棘手的用法简单用法获取NoteExpress格式到剪贴板将剪贴板内容转换在LaTex中使用调用格式效果TeXstudio 4.2.3 Windows 10 20H2 以下内容引自Python cnki2bib包介绍 先决条件 Python3 安装 pip install cnki2bibWinR打开cmd使用以上命令安装 使…

24. 设计原则

总的来说是高内聚低耦合&#xff0c;内聚是把变化点进行封装&#xff0c;耦合还是要有的&#xff0c;只是要尽量少&#xff0c;不同内聚点的联系方式有两种&#xff0c;一种就是继承&#xff0c;一种就是组合。组合又分为基于接口组合还是基于类组合&#xff0c;基于接口就可以…

js中 json详解

var aa {name:"zoumm",age:23};var bb JSON.stringify(aa);console.log(bb); //打印出{"name":"zoumm","age":23} json的语法可以表示以下三种类型的值。 1、简单值&#xff1a;可以在json中表示字符串、数值、布尔和null。 2、对…

试用合肥工业大学学位论文 LaTeX 模板(HFUT_Thesis)

目录编辑器模板下载TeXstudio 4.2.3 Windows 10 20H2 编辑器 编辑器的下载和安装参考Latex下载 —— 倔强菜鸟(转载) 模板下载 见合肥工业大学硕士毕业论文的LaTex模板? 感谢大佬~ 大佬的项目地址&#xff1a;https://github.com/HFUTTUG/HFUT_Thesis/releases 下载下来后…

怎么查询局域网内全部电脑IP和mac地址..

在局域网内查询在线主机的IP一般比较简单&#xff0c;但局域网内全部电脑的IP怎么才能够查到呢&#xff1f;查询到IP后我还要知道对方的一些详细信息&#xff08;如MAC地址、电脑名称等&#xff09;该怎么查询呢&#xff1f;&#xff1f;&#xff1f; 工具/原料 Windows 网络 方…

C语言一阶低通、高通滤波器滤除截止频率外的杂波

目录理论推导产生测试信号sin_cal.csin_cal.h生成波形一阶滤波器FirstOrderFilter.cFirstOrderFilter.h测试低通滤波器高通滤波器IAP15W4K58S4 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 串口示波器&#xff1a;Vofa 1.3.10 理论推导 低通滤波器 …

OAF_开发系列19_实现OAF对话框提示dialogPage(案例)

20150716 Created By BaoXinjian 一、摘要 Oracle dialogPage是OAF提示框的一种用法&#xff0c;具体应用例如在删除数据时&#xff0c;提示用户进行确认是否可以删除 二、实现方法 在CO中添加如下方法 public void processFormRequest(OAPageContext pageContext,OAWebBean we…

设计模式(一)---简单工厂模式

1&#xff0c;简介&#xff1a;简单工厂模式&#xff0c;又称为静态工厂模式&#xff0c;是通过专门定义一个类来负责创建其他类的实例&#xff0c;被创建的实例通常都具有共同的父类。 2&#xff0c;简单工厂模式的结构 2.1&#xff1a;简单工厂的通用结构 2.2&#xff1a;示意…

给LaTex输出的论文PDF加上电子签名

目录问题准备签名插入签名TeXstudio 4.2.3 Windows 10 20H2 参考资料&#xff1a;研究生毕业论文电子签名怎么弄&#xff1f;—— kk肥妹 问题 完成论文之后&#xff0c;需要加上签名&#xff0c;但LaTex输出的结果是PDF格式的 准备签名 准备自己的签名&#xff0c;比如直接…

判断两个矩形相交以及求出相交的区域

问题&#xff1a;给定两个矩形A和B&#xff0c;矩形A的左上角坐标为&#xff08;Xa1,Ya1&#xff09;&#xff0c;右下角坐标为&#xff08;Xa2,Ya2&#xff09;&#xff0c;矩形B的左上角坐标为&#xff08;Xb1,Yb1&#xff09;&#xff0c;右下角 坐标为&#xff08;Xb2,Yb2&…

【MSP430G2553】图形化开发笔记(1) 配置环境

目录CCS的配置下载和安装激活安装Grace并导入CCS安装MSP430Ware并导入CCS安装XDCtools并导入CCS建立工程Welcome介绍开始打开官方点灯Demo平台&#xff1a; Code Composer Studio 6.2.0 Grace 2.2.0 MSP430G2553 LaunchPad™ Development Kit (MSP-EXP430G2ET) CCS的配置 支…