后端开发 - 静态文件与模板技术
静态文件
- 静态文件:static files,和模板概念相反,指内容不需要动态生成的文件
- 比如图片、CSS文件和JavaScript 脚本等
- 添加方法
- 创建 static 目录,它一共和程序模块、templates 在同一目录层级
生成静态文件 URL
- 通过 url_for() 函数来生成
- 此函数在python脚本中,需要从 flask 包中导入,
- 在模板中可以直接使用
- 对于静态文件,此函数需要传入的路由就是 static,同时使用 filename 参数传入相对于 static 文件夹的文件路径
- 花括号部分的调用会返回 /static/pic.jpg
<img src="{{ url_for('static', filename='pic.jpg' ) }}>
添加图标
-
- 准备一个或 ico、png、gif格式的图片,大小一般是 1616、3232、4848、6464
- 把该图片放入 static 目录下,然后在html模板中引用
from flask import Flask, render_template
# 创建 Flask 应用程序实例
app = Flask(__name__)
# 定义路由和视图函数
@app.route("/")
def show_static():
return render_template("tatic.html")
# 运行应用程序
if __name__ == '__main__':
app.run(debug=True, port=5050)
-
- 在 templates 目录下创建 static.html
- 需要放在head标签中
- 通过 link 标签进行链接
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" cintent="width=device-width, initial-scale=1.0" />
<title>静态文件</title>
<link rel="icon" href="{{ url_for('static', filename='logo.png') }}">
</head>
<body>
<h1>静态文件</h1>
</body>
</html>
<script type="text/javascript"></script>
添加图片
-
- 在 static 目录下创建子文件夹 images,把图片都放到这个文件夹中
- 创建子文件夹并不是必须的,
- 同样如果有多个 CSS 文件,也可以创建一个 css 文件夹来管理
- 注意路径要写正确
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" cintent="width=device-width, initial-scale=1.0" />
<title>静态文件</title>
<link rel="icon" href="{{ url_for('static', filename='logo.png') }}">
</head>
<body>
<h1>
<img alt="branch" src="{{ url_for('static', filename='images/branch.gif') }}">霍格沃兹
</h1>
<div>
<img ail="Gryffindor' src="{{ url_for('static', filename='images/Gryffindor.png') }}">
<img ail="hogwarts' src="{{ url_for('static', filename='images/hogwarts.jpg') }}">
</div>
</body>
</html>
<script type="text/javascript"></script>
添加 CSS 文件
- 添加图片与文件,没有排版样式,需要添加CSS定义
-
- 在 static 目录下创建一个 CSS文件 style.css
body {
margin: auto;
max-width: 800px;
font-size: 14px;
font-family: Helvetiva, Arial, sans-serif;
}
/* 霍格沃兹学院 */
.hogwarts {
display: auto;
margin: 0 auto;
height: 300px;
}
/* 小图片 */
.pic {
width: 100px;
}
-
- 在 static.html 页面的标签内引入此 CSS 文件
<head>
<link rel="stylesheet" href="{{ url_for('statuc', filename='style.css) }}">
</head>
-
- 为对应的元素设置 class 属性,和对应的 CSS 定义关联起来,
- templates/index.html:添加 class属性
<body>
<h1>
<img alt="branch" class="pic" src="{{ url_for('static', filename='images/branch.gif') }}">霍格沃兹
</h1>
<div>
<img ail="Gryffindor' class="pic" src="{{ url_for('static', filename='images/Gryffindor.png') }}">
<img ail="hogwarts' class="hogwarts" src="{{ url_for('static', filename='images/hogwarts.jpg') }}">
</div>
</body>
</html>
<script type="text/javascript"></script>
模板技术
渲染模板
- 定义:web程序里,访问一个地址通常会返回一个包含各类信息的HTML页面,其中包含变量和运算逻辑的HTML或其他合适的文本叫做模板
- 执行这些变量替换和逻辑计算工作的过程称为渲染
- Flask 模板是xuan’ra通过 Jinja2 引擎来完成的
- 默认,Flask 会从模块同级的 templates 目录下寻找模板
应用场景价值
- 动态内容:Flask 模板支持将动态数据插入HTML页面,从而创建个性化和交互式的 Web 应用程序
- 代码重用:模板允许在多个页面之间重用常见的HTML组件,减少冗余代码,提高可维护性
- 一致的设计:通过使用模板,可以确保应用程序在设计和布局上保持一致,从而实现专业和统一的用户体验
- 与其他技术的集成:Flask 模板可以与其他前端技术(如CSS框架和JavaScript库) 集成,实现现代化和视觉上吸引人的 Web 界面
模板渲染
-
- 在项目中创建模板目录,目录名称固定为:templates
-
- 在 templates 目录中创建HTML文件,创建完成后,结构如下
./
├── xx.py
└── templates
└── hogwarts.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hogwarts</title>
</head>
<body>
<h1>霍格沃兹平台</h1>
</body>
</html>
<script type="text/javascript"></script>
-
- 视图函数的返回使用 render_template() 渲染对应的HTML文件,如下:
from flask import Flask, render_template
# 创建 Flask 应用程序实例
app = Flask(__name__)
@app.route("/")
def hello():
return render_template("hogwarts.html")
# 运行应用程序
if __name__ == '__main__':
app.run(port=5055, debug=True)
-
- 启动服务,访问默认地址,接口看到渲染的HTML页面
模板语法
- 使用 Jinja2 模板引擎
- 可以放入一部分程序逻辑到模板中处理,但是并不支持所有的python语法
- 尽量仅把和输出控制有关的逻辑操作放到模板当中
- Jinja2 允许模板使用大部分python对象,
- 字符串、列表、字典、元组、整型、浮点型、布尔值,
- 支持基本运算符号: +、-、*、/,等
- 支持比较符号:==、!=,等
- 支持逻辑符号:and、or、not和括号
- 支持:in、is、None、和布尔值–True、False
- 变量代码块{{ }}:主要用于变量的内容显示
- 控制代码块{% %}:主要用于涉及到与逻辑相关的代码块展示
传递数据
- 调用 render_template() 方法时,可以使用关键字传参
-
- 在html的body标签中添加代码,其中 {{ name }}代表模板中所包含的变量信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hogwarts</title>
</head>
<body>
<h1>霍格沃兹平台</h1>
<h2>{{ name }}</h2>
</body>
</html>
<script type="text/javascript"></script>
-
- 视图函数中调用方法 render_template(‘hogwarts.html’, name=‘aaabbb’)的时候,通过关键字传参到html页面当中
from flask import Flask, render_template
# 创建 Flask 应用程序实例
app = Flask(__name__)
@app.route("/data")
def hogwarts():
return render_template("hogwarts.html", name="hogwarts")
# 运行应用程序
if __name__ == '__main__':
app.run(port=5055, debug=True)
-
- 启动服务,访问 /data 路由,name变量的位置会展示传入的值,
判断语法
- Flask 中的 Jinja2 模板提供了多种控制结构,
# 条件控制语句
<!-- if 条件判断--->
{% if 条件表达式 %}
.......
{% elif 条件表达式 %}
.......
{% else %}
.......
{% endif %}
from flask import Flask, render_template
# 创建 Flask 应用程序实例
app = Flask(__name__)
@app.route("/person")
def person():
person = {
"name": "lily",
"age": 18,
"gender": "female"
}
return render_template("person.html", person=person)
# 运行应用程序
if __name__ == '__main__':
app.run(port=5055, debug=True)
- templates 目录下创建 person.html 文件
- 模板中,Jinja2 支持使用 点 . 获取变量的属性,比如person字典中的gender简直通过 . 获取,即 person.gender
<!-- person.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<p>
您好,
{% if person.gender == "male" %}
{{ person.name }} 先生
{% else %}
{{ person.name }} 女士
{% endif %}
</p>
</body>
</html>
<script type="text/javascript"></script>
- 启动服务,访问 /person 路由,可根据判断结果显示对应的信息
循环语法
<!-- for 循环 -->
{% for row in list_or_dict %}
{{ row }}
{% endfor %}
from flask import Flask, render_template
# 创建 Flask 应用程序实例
app = Flask(__name__)
@app.route("/people")
def people():
people = [
{
"name": "lily",
"age": 18,
"gender": "female"
},
{
"name": "tom",
"age": 19,
"gender": "male"
},
]
return render_template("people.html", people=people)
# 运行应用程序
if __name__ == '__main__':
app.run(port=5055, debug=True)
- templates 目录下创建 people.html文件
<!-- people.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
{% for p in people %}
<p>
Hello,
{% if p.gender == "male" %}
Mr. {{ p.name }}
{% else %}
Ms. {{ p.name }}<br />
{% endif %}
Your age is {{ p.age }}<br />
Your gender is {{ p.gender }}<br />
</p>
{% endfor %}
</body>
</html>
<script type="text/javascript"></script>
- 启动服务,访问 /people 路由,页面中会显示所有的人员信息,并通过性别来判断显示信息
继承语法
- 模板继承允许创建一个基础的骨架模板,包含网站的通用元素,并且定义子模板可以重载的区域
- 举例:顶部的导航栏、底部的页脚部分,等等
- 将这些相同的内容集合放入父模板中,不同的地方使用其他东西展位,然后在不同的页面中继承这个父模板,再填充不同的内容
-
-
定义父模板 语法
- 标签 block 用于在父模板中预留区域,留给子模版填充差异性内容,名字不能相同,父模板也可以使用上下文中传递过来的数据
<!-- 父模版中定义,子模板可以直接继承重写 -->
{% block 自定义名称 %}
{% endblock %}
{% extends '父模板' %}
- 示例
-
- layout.html 文件是父模板,也可以看成一个骨架,可以让继承者对 title、content、footer三个地方进行定制
<!-- layout.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %} © Copyright 2023 by
<a href="https://ceshiren.com">测试人社区</a>. {% endblock %}
</div>
</body>
</html>
<script type="text/javascript"></script>
-
- son.html 文件是子模版,用来继承父模板,并对title、content机械能定会之
<!-- son.html -->
{% extends "layout.html" %}
{% block title %}Son Page{% endblock %}
{% block content %}
<h1>子模版</h1>
<button>按钮</button>
{% endblock %}
from flask import Flask, render_template
# 创建 Flask 应用程序实例
app = Flask(__name__)
@app.route("/extend")
def extend():
return render_template("son.html")
# 运行应用程序
if __name__ == '__main__':
app.run(port=5055, debug=True)
模板导入
- 定义:将另一个模板加载到当前模板中,直接渲染,
- 模板继承和类的继承含义是一样的,
- 为了提高代码重用,减轻开发工作量
- 导入语法
{% include '文件名' %}
<a>首页</a>
<a>关于</a>
{% extends "layout.html" %}
{% block title %}Son Page{% endblock %}
{% include "top.html" %}
{% block content %}
<h1>子模版继承</h1>
<button>按钮</button>
{% endblock %}
- 导入 top.html,该模板直接加载并渲染到当前模块中
导入列表
- 也可以导入一个模板列表,程序会按照顺序一次寻找模板文件,
- 第一个被找到的模板文件将被加载渲染,后续的会忽略
{% include ['footer.html','bottom.html','top.html'] %}
忽略报错
- 如果都没有找到模板,程序会报错,要忽略报错,需要增加 ignore missing,用来忽略 include 语句
{% include ['footer/html','bottom.html','end.html'] ignore missing %}