(十一)Flask模板引擎jinja2

模板引擎Jinja2

一、简介及基本使用:

Flask使用Jinja2作为默认的模板引擎。Jinja2是一个功能强大且易于使用的模板引擎,它允许我们在HTML中嵌入Python代码,并通过将模板和数据进行渲染来生成动态内容。

实战之在Flask中使用Jinja2模板引擎:

  1. 在Flask应用程序的根目录下创建一个名为templates的文件夹,用于存放模板文件。

  2. 创建一个名为index.html的模板文件,在其中可以使用Jinja2语法来插入动态内容,即使用双花括号{{ }}来插入Jinja2表达式,这些表达式将在渲染模板时被替换为实际的值。

    <!DOCTYPE html>
    <html>
    <head><title>Flask Template Engine</title>
    </head>
    <body><h1>Welcome to {{ title }}</h1><p>{{ message }}</p>
    </body>
    </html>
    
  3. 在Flask应用程序中导入render_template函数,并在路由函数中调用该函数以渲染模板并返回响应。

    from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')
    def home():title = 'Flask Template Engine'message = 'Hello, World!'return render_template('index.html', title=title, message=message)if __name__ == '__main__':app.run()

    在视图函数中,定义了titlemessage两个变量,并将其传递给render_template()函数。

    render_template()函数接收模板名称作为第一个参数,以及可选的关键字参数用于传递给模板的数据。

    render_template()函数将根据模板文件中的Jinja2语法进行渲染,并返回渲染后的HTML内容作为响应发送给客户端。

通过使用Jinja2模板引擎,可以将静态HTML页面与动态生成的内容结合起来,实现更灵活、可维护和可重用的视图层逻辑。在模板中,可以使用条件语句、循环语句、过滤器等功能,对数据进行处理和展示,从而创建出更丰富的用户界面。

先简单将一讲Jinja2模板引擎的一些特性和用法【下面都会详细讲解~】:

  1. 模板语法:Jinja2使用{{ ... }}来标记表达式,表示将变量插入到模板中。例如,{{ name }}将会在模板中显示变量name的值。而使用{% ... %}来标记控制结构和语句,如条件语句、循环语句等。

  2. 变量:可以在模板中使用变量来动态地渲染内容。通过传递变量给模板进行渲染,例如:render_template('index.html', name=name)。在模板中,可以使用{{ variable_name }}语法来插入变量的值。

  3. 过滤器:Jinja2提供了许多内置的过滤器函数,用于对变量进行处理和格式化。例如,{{ name|capitalize }}会将变量name的首字母大写。还可以自定义过滤器函数,使用@app.template_filter()装饰器注册为模板过滤器。

  4. 控制结构:Jinja2支持各种控制结构,如if语句、循环语句和宏。通过使用{% if ... %}...{% endif %}来实现条件语句,使用{% for ... in ... %}...{% endfor %}来实现循环语句,以及使用{% macro ... %}...{% endmacro %}来定义宏。

  5. 继承:Jinja2允许模板之间进行继承,以提高代码的可重用性和可维护性。通过使用{% extends ... %}指令,一个模板可以继承另一个模板,并在其中使用{% block ... %}...{% endblock %}来替换或扩展基础模板中的内容。

  6. 模板包含:Jinja2支持模板包含,允许将一个模板嵌入到另一个模板中。通过使用{% include ... %}指令,可以在模板中引用其他模板文件,实现代码的复用。

  7. 自定义全局变量和函数:可以在Flask应用中注册自定义的全局变量和函数,使其在所有模板中可用。通过使用app.jinja_env.globals['variable_name'] = value来注册全局变量【需要注意,在注册模板全局变量时,建议将其放置在一个在应用启动时运行的函数(如before_first_request装饰的函数)中,以确保全局变量在所有请求中都可用】;使用@app.template_global()装饰器来注册全局函数。

二、支持的Python数据类型:

Flask的Jinja2模板引擎支持以下Python数据类型:

  1. 字符串(String):用于表示文本数据。
  2. 整数(Integer):用于表示整数值,如1、2、3等。
  3. 浮点数(Float):用于表示带有小数部分的数值,如3.14、2.5等。
  4. 布尔值(Boolean):用于表示真或假的值,True或False。
  5. 列表(List):用于表示有序的集合,可以包含任意类型的元素。例如:[1, 2, 'a', True]
  6. 元组(Tuple):类似于列表,但是是不可变的,也就是说不能修改元素的值。例如:(1, 2, 'a', True)
  7. 字典(Dictionary):用于表示键值对的集合,其中每个元素由一个键和一个对应的值组成。例如:{'name': 'John', 'age': 25}
  8. 集合(Set):用于表示无序且唯一的元素集合,不允许重复的元素。例如:{'apple', 'banana', 'orange'}

除了上述基本数据类型之外,Jinja2模板还支持使用过滤器对数据进行处理和格式化,以及使用控制结构如条件语句和循环语句来控制模板的渲染流程。

需要注意的是,Jinja2模板引擎并不限制使用上述数据类型,可以在模板中使用任何Python支持的数据类型。如果有自定义的类或对象,也可以将其传递给模板,并在模板中访问其属性或调用其方法。

(1)实战在模板中使用Python常见的基本数据类型:

from flask import Flask, render_templateapp = Flask(__name__)@app.route("/index", methods=['GET', 'POST'])
def index():context = {'k1': 123,'k2': [11, 22, 33],'k3': {'name': 'oldboy', 'age': 84}}return render_template('index.html', **context)if __name__ == '__main__':app.run()
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>{{ k1 }}</h1><h1>{{k2.0}}  {{k2[0]}}</h1><h1>{{k3.name}}  {{k3['name']}}  {{k3.get('name', 888)}}</h1>
</body>
</html>

在这里插入图片描述

(2)实战在模板中使用匿名函数:

from flask import Flask, render_templateapp = Flask(__name__)@app.route("/index", methods=['GET', 'POST'])
def index():context = {'k1': 123,'k2': [11, 22, 33],'k3': {'name': 'oldboy', 'age': 84},'k4': lambda x: x+1}return render_template('index.html', **context)if __name__ == '__main__':app.run()
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>{{ k1 }}</h1><h1>{{k2.0}}  {{k2[0]}}</h1><h1>{{k3.name}}  {{k3['name']}}  {{k3.get('name', 888)}}</h1><h1>{{k4(66)}}</h1>
</body>
</html>

在这里插入图片描述

(3)实战在模板中使用普通函数:

from flask import Flask, render_templateapp = Flask(__name__)def gen_input(value):return "<input value='%s' />" %value@app.route("/index", methods=['GET', 'POST'])
def index():context = {'k1': 123,'k2': [11, 22, 33],'k3': {'name': 'oldboy', 'age': 84},'k4': lambda x: x+1,'k5': gen_input}return render_template('index.html', **context)if __name__ == '__main__':app.run()
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>{{ k1 }}</h1><h1>{{k2.0}}  {{k2[0]}}</h1><h1>{{k3.name}}  {{k3['name']}}  {{k3.get('name', 888)}}</h1><h1>{{k4(66)}}</h1><h1>{{k5(99)}}</h1>
</body>
</html>

如果不加 | safe,就直接显示字符串而不是input标签。这是Flask防止xss攻击。默认用户输入都是不安全的。

在这里插入图片描述

两种解决方法:

  • 一种是前端加 | safe
  • 一种是后端使用markup。
    <h1>{{k5(99) | safe}}</h1>
from flask import Flask, render_template, Markupapp = Flask(__name__)def gen_input(value):# return "<input value='%s' />" %valuereturn Markup("<input value='%s' />" %value)

三、template_global()装饰器:

问题引入:

当我们在每一个模板里都想自定义一些函数: 如果每一个视图里都手动加,是不是太麻烦了!

解决方法:

  • 这就引出了template_global()装饰器,使用它装饰的函数在每一个模板里都可以直接使用!!!

    template_global()装饰器用于将一个函数注册为全局模板变量。被该装饰器修饰的函数可以在所有的模板中使用,并且不需要在每个视图函数中都传递一遍。

@app.template_global()
def sb(a1, a2):return a1 + a2
<body><h1>{{sb(1,2)}}</h1>
</body>

需要注意的是,在使用template_global装饰器时,函数名就是全局模板变量的名称。因此,在模板中调用全局模板变量时,直接使用函数名即可。

通过使用template_global装饰器,我们可以方便地注册全局模板变量,提高代码的重用性和可维护性,并简化视图函数与模板之间的数据传递过程。

四、template_filter装饰器:

  1. 常规用法:

    template_filter用于将一个函数注册为模板过滤器。被该装饰器修饰的函数可以在模板中通过过滤器的名称进行调用,并对数据进行处理和格式化。

    实战使用:

from flask import Flask, render_templateapp = Flask(__name__)@app.template_filter()
def reverse_string(string):return string[::-1]@app.route('/')
def home():name = 'John Doe'return render_template('index.html', name=name)if __name__ == '__main__':app.run()

在上述示例中,定义了一个名为reverse_string的函数,并使用template_filter()装饰器将其注册为模板过滤器。这个函数接受一个字符串参数,并返回反转后的字符串。

home视图函数中,将用户的姓名传递给模板,并在模板中使用{{ name|reverse_string }}来调用模板过滤器。这样,在模板中会自动将用户的姓名进行反转处理。

在使用template_filter装饰器时,函数名就是模板过滤器的名称。因此,在模板中调用模板过滤器时,使用|管道符号将变量与过滤器名称分隔开。

在这里插入图片描述

  1. 技巧使用:
from flask import Flask, render_templateapp = Flask(__name__)@app.template_filter()
def add_all(a1, a2, a3):return a1 + a2 + a3@app.route('/')
def home():return render_template('index.html')if __name__ == '__main__':app.run()
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>{{ 1 | add_all(2,3) }}</h1>
</body>
</html>

在这里插入图片描述

五、Flask模板的继承:

Flask模板的继承是一种在多个模板中共享相同布局和结构的方式。通过使用模板的继承,我们可以定义一个基础模板,其中包含通用的 HTML 结构和样式,并在其他模板中继承这个基础模板,只需专注于特定内容的定义。

实战讲解:

base.html(基础模板):

<!DOCTYPE html>
<html>
<head><title>{% block title %}{% endblock %}</title>
</head>
<body><header>{% block header %}<h1>Welcome to my website!</h1>{% endblock %}</header><main>{% block content %}{% endblock %}</main><footer>{% block footer %}&copy; 2023 My Website - GuHanZhe. All rights reserved.{% endblock %}</footer>
</body>
</html>

home.html(继承自base.html):

{% extends 'base.html' %}{% block title %}Home Page
{% endblock %}{% block content %}<h2>Welcome to the Home Page!</h2><p>Content specific to the home page goes here.</p>
{% endblock %}

about.html(继承自base.html):

{% extends 'base.html' %}{% block title %}About Page
{% endblock %}{% block content %}<h2>About Us</h2><p>Content specific to the about page goes here.</p>
{% endblock %}

在上述示例中,base.html 是一个基础模板,定义了整个网页的结构和通用元素。其他模板(home.html 和 about.html)通过 {% extends 'base.html' %} 指令继承自 base.html,并可以使用 {% block %} 块来替换或扩展基础模板中的内容。

每个子模板都可以通过 {% block %} 块来定义自己特定的内容,这些块将在渲染时插入到相应的位置。例如,在 home.html 中的 {% block content %} 块中定义了特定于首页的内容。

通过使用模板继承,可以避免在每个模板中重复编写相同的 HTML 结构和样式,提高代码的可重用性和可维护性。

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

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

相关文章

colormap与colorbar应用

一&#xff0c;colormap 常见色度枚举值如下 应用如下 img cv2.applyColorMap(img, cv2.COLORMAP_JET) cv2.imshow(img,img) cv2.waitKey(0) cv2.destroyAllWindows() 常用的COLORMAP_JET效果如下&#xff0c;该模式常用于生成热力图 二&#xff0c;colorbar colorbar所有…

python画出2行4列个子图

代码 import matplotlib.pyplot as plt# 数据 areas [50, 80, 120] shenzhen_prices [1500, 2000, 2500] guangzhou_prices [1200, 1800, 2300] zhengzhou_prices [800, 1200, 1500]# 创建一个包含2行4列共8个子图的图表 fig, axs plt.subplots(2, 4, figsize(14, 8))def…

一文搞懂Transformer

近期Transformer系列模型的出现&#xff0c;增加了CV领域的多样性。但是Transformer这一不同领域的模型对学习者来说需要一个细致的学习过程.下面就是本菜鸟总结学习路线。 Transformer是基于attention机制。而attention机制又在Encoder、Decode中。本篇博客将从Attention->…

sqli-labs(Less-3)

1. 通过构造id1’ 和id1’) 和id1’)–确定存在注入 可知原始url为 id(‘1’) 2.使用order by 语句猜字段数 http://127.0.0.1/sqlilabs/Less-3/?id1) order by 4 -- http://127.0.0.1/sqlilabs/Less-3/?id1) order by 3 --3. 使用联合查询union select http://127.0.0.1…

Sentinel 流控规则

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 SpringbootDubboNacos 集成 Sentinel&…

探索未来,开启无限可能:打造智慧应用,亚马逊云科技大语言模型助您一臂之力

文章目录 什么是大模型&#xff1f;大模型训练方法亚马逊云科技推出生成式AI新工具 —— aws toolkit使用教程 总结 什么是大模型&#xff1f; 近期&#xff0c;生成式大模型是人工智能领域的研究热点。这些生成式大模型&#xff0c;诸如文心一言、文心一格、ChatGPT、Stable …

文心生物计算大模型重磅升级,构象预测准确度全面提升!

文心生物计算大模型家族又迎来了重磅的升级&#xff1a;蛋白质-小分子对接构象预测模型HelixDock&#xff0c;以及蛋白-蛋白复合物结构预测模型HelixFold-Multimer准确度全面提升。这两项新技术可以大幅提升蛋白质-小分子的对接构象及蛋白-蛋白复合物结构预测的精度&#xff0c…

《QT从基础到进阶·二十一》QGraphicsView、QGraphicsScene和QGraphicsItem坐标关系和应用

前言&#xff1a; 我们需要先由一个 QGraphicsView&#xff0c;这个是UI显示的地方&#xff0c;也就是装满可见原色的Scene&#xff0c;然后需要一个QGraphicsScene 用来管理所有可见的界面元素&#xff0c;要实现UI功能&#xff0c;我们需要用各种从QGraphicsItem拼装成UI控件…

Flutter笔记:使用Flutter构建响应式PC客户端/Web页面-案例

Flutter笔记 使用Flutter构建响应式PC客户端/Web页面-案例 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/detai…

CentOS7.9安装docker

在CentOS 7.9上安装Docker可以通过官方的Docker安装脚本或者使用系统包管理工具来完成 本次使用系统包管理工具 打开终端&#xff0c;以root权限登录系统。 安装所需的依赖&#xff1a; yum install -y yum-utils device-mapper-persistent-data lvm2 添加Docker的官方仓库…

【java学习—十四】反射机制调用指定方法、指定属性(5)

文章目录 1. 调用指定方法2. 调用指定属性 1. 调用指定方法 通过反射&#xff0c;调用类中的方法&#xff0c;通过 Method 类完成。步骤&#xff1a;     ①通过 Class 类的 getMethod(String name,Class...parameterTypes) 方法取得一个 Method 对象&#xff0c;并设置此…

前端算法面试之堆排序-每日一练

如果对前端八股文感兴趣&#xff0c;可以留意公重号&#xff1a;码农补给站&#xff0c;总有你要的干货。 今天分享一个非常热门的算法--堆排序。堆的运用非常的广泛&#xff0c;例如&#xff0c;Python中的heapq模块提供了堆排序算法&#xff0c;可以用于实现优先队列&#xf…