赞
踩
⭐ 简介:大家好,我是zy阿二,我是一名对知识充满渴望的自由职业者。
☘️ 最近我沉溺于Python的学习中。你所看到的是我的学习笔记。
❤️ 如果对你有帮助,请关注、点赞,让我们共同进步。有不足之处请留言指正!
1. Flask打造 Python Web 开发的灵活框架,实现简易登录。入门篇
2. Flask中默认集成了Jinja2,用于web应用程序中生成动态内容。进阶篇【本文】
Jinja2是一个流行的HTML引擎,用于在Flask等Python Web应用程序中生成HTML,XML或其他文本格式的动态内容。Flask中默认集成了Jinja2。
Jinja2允许开发人员将动态内容与静态HTML代码分离。通过在HTML中使用Jinja2语法,可以将动态内容以一种可读性强且易于维护的方式与HTML混合在一起。Jinja2还支持过滤器,控制结构和继承等高级功能。
在Flask中,可以通过将Jinja2模板存储在应用程序的“templates”目录中,并使用Flask的内置render_template函数将模板渲染为响应发送给客户端。例如,在Flask应用程序中渲染一个名为“index.html”的模板的代码如下:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html', name='World')
if __name__ == '__main__':
app.run()
在此示例中,应用程序使用render_template函数渲染了“index.html”,并将参数“name”设置为“World”。在模板中,可以使用Jinja2语法来访问该参数,例如:
<!DOCTYPE html>
<html>
<head>
{# 我是注释 #}
<title>Hello {{ name }}!</title>
</head>
<body>
{# 我是注释 #}
<h1>Hello {{ name }}!</h1>
</body>
</html>
在这个例子中
{{ name }}
语法来引用传递给它的参数“name”,从实现不同用户显示不同的HTML内容。(即:动态HTML内容){# 我是注释 #}
是Jinja2注释的格式。当我们想要根据列表、字典或其他可迭代对象在HTML上生成一个列表时,我们就可以这样做。
下面我们创建了一个名为 "my_list.html " 的文件,并写入内容如下:
<!DOCTYPE html>
<html>
<head>
<title>My List</title>
</head>
<body>
<h1>My List</h1>
<ul>
{% for item in my_list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
假设一个名为 “my_list” 的Python列表,在模板中使用for循环来遍历这个列表,并使用{{ item }}
在每个项目之前创建一个HTML列表项。
为了在Flask应用程序中使用此模板,我们可以使用"render_template"函数并将"my_list"作为参数传递给模板。例如:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
my_list = ['item 1', 'item 2', 'item 3']
return render_template('my_list.html', my_list=my_list)
if __name__ == '__main__':
app.run()
运行并打开后将得到如下页面:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z9xnvGLo-1677990858750)(C:\Users\张义\AppData\Roaming\Typora\typora-user-images\image-20230305122742840.png)]
当然,我们可以通过修改 ”my_list“ 中的内容来实现更加丰富的动态页面。
值得注意的是 :
{{ item }}
在Jinja2中引用变量需要2个花括号包裹。如需引用多个,每一个变量都需要2个花括号包裹。例如{{ item1 }}{{ item2 }}
for循环也有严格的格式{% for ... in .... %}
而且{% endfor %}
也是必须的。表示for循环代码结束的位置,循环的内容则写在中间。
Jinja2的for循环是直接完成的,它不同于Python还有break
方法来提前中断循环。
{% for item in my_list %}
<li>{{ item }}</li>
{% endfor %}
假设 my_list 是一个二维数组,每个值中包含,书名,作者,价格和日期。根据my_list 生成一个带有表格的HTML页面。
“my_list.html” 文件内容如下:
<!DOCTYPE html> <html> <head> <title>Book List</title> <!-- 为了使得表格看上去美观一点,我引入了bootstrap。虽然可以使用原生CSS美化,但是会让代码变得太长,不适合演示。不懂bootstrap的可以选择性的屏蔽掉所有的class 或者直接删除下方的link标签--> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h1>Book List</h1> <table class="table table-bordered table-striped"> <thead class="thead-dark"> <tr> <th scope="col">Book</th> <th scope="col">Author</th> <th scope="col">Price</th> <th scope="col">Date</th> </tr> </thead> <tbody> {% for row in my_list %} <tr> <td>{{ row[0] }}</td> <td>{{ row[1] }}</td> <td>{{ row[2] }}</td> <td>{{ row[3] }}</td> </tr> {% endfor %} </tbody> </table> </div> </body> </html>
py文件内容如下:
from flask import Flask, render_template app = Flask(__name__) # 运行代码后访问: `http://localhost:5000` @app.route('/') def index(): my_list = [['Book 1', 'Author 1', 19.99, '2020-01-01'], ['Book 2', 'Author 2', 29.99, '2021-02-02'], ['Book 3', 'Author 3', 39.99, '2022-03-03'], ['Book 4', 'Author 4', 49.99, '2023-04-04'], ['Book 5', 'Author 5', 59.99, '2024-05-05']] return render_template('my_list.html', my_list=my_list) if __name__ == '__main__': app.run()
运行代码后访问: http://localhost:5000
,得到如下页面:
{% if .... %}
{% elif ... %}
{% endif %}
{%..%}
的结构和必须在if结束的位置加上{% endif %}
<!DOCTYPE html> <html> <head> <title>Book List</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h1>Book List</h1> <div class="table-responsive"> <table class="table table-hover"> <thead class="thead-light"> <tr> <th scope="col">Book</th> <th scope="col">Author</th> <th scope="col">Price</th> <th scope="col">Date</th> </tr> </thead> <tbody> {% for row in my_list %} <!-- 这次我们在循环内加上了if语句做条件判断,如果价格小于20,就给这一行加上黄色背景,如果价格大于40,就给这一行加上红色背景,否则就不加背景。这里的row[2]就是价格,row[0]是书名,row[1]是作者,row[3]是日期。 --> {% if row[2] < 20 %} <tr style="background-color: yellow;"> {% elif row[2] > 40 %} <tr style="background-color: red;"> {% else %} <tr> {% endif %} <td>{{ row[0] }}</td> <td>{{ row[1] }}</td> <td>{{ row[2] }}</td> <td>{{ row[3] }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> </body> </html>
执行代码后,访问: http://localhost:5000
得到如下页面
首先创建一个“index.html” 写入代码:
<!DOCTYPE html> <html> <head> <title>{{ title }}</title> </head> <body> {% if user %} <h1>欢迎你, {{ user.username }}!</h1> {% else %} <h1>欢迎来宾!</h1> {% endif %} </body> </html>
在上面的html文件中,使用双花括号“{{}}”插入变量和使用“{% %}”控制流,如果有user,则显示欢迎用户的消息,否则显示欢迎来宾的消息。其中,user和title是在Flask应用程序中定义的变量。
然后在py文件中写入:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
user = {'username': 'John'}
return render_template('index.html', title='Home', user=user)
if __name__ == "__main__":
app.run(debug=True)
{% block name %} ... {% endblock %}
{% block %}
是 Jinja2 模板引擎的一个核心功能,它允许您定义一个模板块,该模板块可以在子模板中被重写和填充。类似python中的class封装一些固定的方法,减少代码的重用率。
具体来说,{% block %}
标记定义了一个命名的模板块,可以将该模板块视为一个占位符。在父模板中,该模板块可能包含一些默认内容,但是在子模板中,该模板块可以被重写,并且将显示子模板中的新内容。以下是一个简单的示例:
首先创建一个base.html
模版:
<!DOCTYPE html> <html> <head> <title>{% block title %} base.html 模版的title {% endblock %}</title> </head> <body> <div class="header"> {% block header %} base.html 模版的 Header{% endblock %} </div> <div class="content"> {% block content %} base.html 模版的 Content{% endblock %} </div> <div class="footer"> {% block footer %} base.html 模版的 Footer{% endblock %} </div> </body> </html>
再创建一个home.html
模版:
{% extends 'base.html' %}
{% block title %}
主页
{% endblock %}
{% block header %}
<h1>欢迎来到我的主页</h1>
{% endblock %}
{% block content %}
<p>我是一个有理想有目标有远见有卓越智慧的肉肉!!</p>
{% endblock %}
在home.html
模板中,我们继承了 base.html
模板,并重写了 title
、header
和 content
中的内容,以创建一个和 base.html
结构相同但是内容却不一样的主页。就像是python中创建一个类,继承另一个类,又重写了父类方法。
再创建一个about.html
模板:
{% extends 'base.html' %}
{% block title %}
关于我
{% endblock %}
{% block header %}
<h1>我的简介</h1>
{% endblock %}
{% block content %}
<p>我是一盒坚持学习不断进取的猪肉!!</p>
{% endblock %}
新的about.html
模板,我们又继承了 base.html
模板,并再次重写了 title
、header
和 content
中的内容,所以这3个模版的HTML结构都是相同的,但是其中的内容是不同的。
最后,我们创建一个py文件,代码如下:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('home.html')
@app.route('/about')
def about():
return render_template('about.html')
if __name__ == '__main__':
app.run(debug=True)
运行,然后访问 http://localhost:5000
和 http://localhost:5000/about
,以查看生成的 HTML 页面。
最后你可以自己尝试重新修改以下“ base.html 模版的 Footer ”的内容。
总结: {% block name %} ... {% endblock %}
的目的就是为了减少代码的重用率。
{% macro macro(args) %}
… {% endmacro %}
定义一个函数定义一个可重用的模板块,称为“宏”(Macro)。 它类似于一个函数,接受一个或多个参数,可以在模板中多次调用,以避免重复编写相同的代码。宏可以带有参数,这些参数可以在宏内部使用,用于生成特定的输出。类是于python中的 def macro(*arg):
在函数内部执行完成后通过return
输出结果。
例如,以下代码定义了一个名为 hello
的宏,它带有一个参数 name
,并在模板中使用了调用了他3次:
{% macro hello(name) %}
<h1>你好我好大家好,我是 {{ name }}!</h1>
{% endmacro %}
{{ hello('John') }}
{{ hello('Binbin') }}
{{ hello('Liya') }}
下面是一个完整的 Flask 和 Jinja2 模板的示例。
首先创建一个“index.html” 写入代码:
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
</head>
<body>
{% macro hello(name) %}
<h1>你好我好大家好,我是 {{ name }}!</h1>
{% endmacro %}
{{ hello('John') }}
{{ hello('Binbin') }}
{{ hello('Liya') }}
</body>
</html>
py文件代码如下:
from flask import Flask, render_template
from jinja2 import Template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
执行代码后,访问 http://localhost:5000
后得到如下页面:
在这个示例中,我们定义了一个hello
宏,并调用了他3次,返回了3个带有固定字符串“你好我好大家好,我是 ”和自定义name的3个h1标签。实现了简单的避免代码重用的方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。