Flask基础快速上手

0. URL传参

0.1 URL传参有什么用?

可以使用相同的URL指定不同的参数,来访问不同的内容。

0.2 URL传参的语法是什么?

传递参数的语法是:'/<参数名>/'
注意2点:
参数需要放在一对<>(尖括号)内;
视图函数中需要设置同URL中相同的参数名。

0.3 URL传参的2个案例

例1:

### 从Flask框架中导入Flask类
from flask import Flask
### 传入__name__初始化一个Flask实例
app = Flask(__name__)

### 这个路由将根URL映射到hello_world函数上
@app.route('/')

def hello_world():			### 定义视图函数
    return '这是url传参演示!'   ### 返回响应对象

### 定义路由,传递的参数名是name,因此函数的形参也是name。视图函数的名字不做要求,随意 = 不重名 + 见名知意
@app.route("/user/<name>")
### 定义试图函数fun01,形参是name
def fun01(name):
    return f"接收到的名称是:{name}"

### 如果该模块直接被执行,那么__name__ == '__main__'条件为真,开始执行下面代码。当该模块被导入时,无法执行代码。
if __name__ == '__main__':
### 指定默认主机是127.0.0.1,port是5000
    app.run(debug=True)

在这里插入图片描述
将上述代码中的【@app.route("/user/")】改为【@app.route("/")】试试:
在这里插入图片描述
例2:

### 从Flask框架中导入Flask类
from flask import Flask
### 传入__name__初始化一个Flask实例
app = Flask(__name__)

### 这个路由将根URL映射到hello_world函数上
@app.route('/')

def hello_world():			### 定义视图函数
    return '这是url传参演示!'   ### 返回响应对象

### 定义路由,传递的参数名是name,因此函数的形参也是name。视图函数的名字不做要求,随意 = 不重名 + 见名知意,比如fun01
@app.route("/user/<name>")
### 定义试图函数fun01,形参是name
def fun01(name):
    return f"接收到的名称是:{name}"

### 定义路由,传递的参数名是【整型】的id,因此函数的形参也是id,视图函数的名字不做要求,随意 = 不重名 + 见名知意,比如fun02
@app.route("/news/<int:id>")
def fun02(id):
    return f"接收到的id是:{id}"
### 如果该模块直接被执行,那么__name__ == '__main__'条件为真,开始执行下面代码。当该模块被导入时,无法执行代码。
if __name__ == '__main__':
### 指定默认主机是127.0.0.1,port是5000
    app.run(debug=True)

在这里插入图片描述
在这里插入图片描述

1. URL反转

1.1 URL反转是什么?

有时候,在作网页重定向或是模板文件时需要使用在视图函数中定义的URL,我们必须根据视图函数名称得到当前所指向的URL,这就是URL反转。
正转:通过url查看视图函数中的内容,比如输入:http://127.0.0.1:5000/,看到hello world。
反转:通过视图函数名字得到视图函数指向的url。
用途:页面跳转和重定向

1.2 URL反转的语法

语法:导入url_for,url_for(‘视图函数名字’,参数)

1.3 URL反转的使用

### 导入Flask及url_for模块
from flask import Flask,url_for
### Flask初始化
app = Flask(__name__)

### 定义根路由
@app.route("/")
def index():
    ### fun01是视图函数的名字。 id的类型要相同。
    ### 哪里有url_for,哪里就有URL反转
    url1 = (url_for("fun01",id = 12580))
    return f"URL反转的内容是:{url1}"

###只是定义路由。id的类型要相同。
@app.route("/news/<int:id>")
###函数名fun01与url_for的第一个参数必须同名。
def fun01(id):
    return f"你的请求参数是:{id}"

### 如果该模块直接被执行,那么执行代码块,如果该模块被导入,那么不执行代码块
if __name__ == "__main__":
    app.run(debug = True)

在这里插入图片描述

2. 页面跳转和重定向

用户在访问某个页面的时候,我们希望他登录后才能访问该页面,如果此时他没有登录,系统就让浏览器由当前页面跳转到登录页面,这里就涉及页面重定向问题。所谓页面重定向,就是用户在打开某个页面的时候,我们期望页面跳转到另一个指定的页面,让用户完成某种操作或执行某个动作。
Flask中提供了重定向函数redirect(),该函数的功能就是跳转到指定的URL。

### 导入Flask和url_for和redirect模块
from flask import Flask,url_for,redirect
### Flask初始化
app = Flask(__name__)

### 根路由
@app.route("/")
### 定义试图函数
def index():
    ### 打印输出
    print("首先访问了index()这个函数")
    ### URL反转
    url1 = url_for("user_login")
    ### 网页重定位
    return redirect(url1)

### 定义路由
@app.route("/user_login")
### 定义试图函数
def user_login():
    ### 返回值
    return "这是用户登录的页面,请你登录才能访问首页"

### 当直接执行该模块时,条件为真,执行代码块;当被当做模块导入时,代码不执行
if __name__ == '__main__':
    app.run()

在这里插入图片描述

2.1 问题

(1)什么是Flask?(2)URL如何传递参数?(3)网页如何重定向?

3.Jinja 2 模板引擎

3.1 模板引擎是什么及使用

在Flask中通常使用Jinja 2模板引擎来实现复杂的页面渲染。

templates文件夹下的index.html配置如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"><!-- 设置网页编码-->
    <title>这是首页</title><!-- 设置网页标题-->
    <h1>这是首页文字</h1><!-- 设置H1标题-->
</head>
<body>
</body>
</html>

templates文件夹下的user.html配置如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"><!-- 设置网页编码-->
    <title>这是用户中心</title><!-- 设置网页标题-->
    <h1>这是用户中心!</h1><!-- 设置h1标题-->
</head>
<body>
</body>
</html>

app.py配置如下:

# 导入flask模块
from flask import Flask
# 导入render_template模块
from flask import render_template

# Flask初始化
app = Flask(__name__)
# 定义根路由
@app.route("/")

# 定义视图函数
def index():
    # 使用render_template()方法渲染模板
    return render_template("index.html")

#定义路由,实践时比如/user/yjg,比如/user/yj
@app.route("/user/<username>")
#定义视图函数
def user(username):
    # 使用render_template()方法渲染模板
    return render_template("user.html")

# 当直接执行该模块时,条件为真,执行代码块;当该模块被其他模块调用时,不执行代码块
if __name__ == '__main__':
    app.run(debug = True)

运行结果如下:
在这里插入图片描述
Flask通过render_template()函数来实现模板的渲染。要使用Jinja 2模板引擎,需要使用fromflask import render_template命令导入render_template函数。在视图函数的return方法中,render_template()函数的首个参数声明使用哪一个模板文件。

注意:在render_template()函数中,有一个参数是用来声明使用哪个静态文件,除此参数之外,还可以有多个参数。

3.2 向模板中传递参数

Flask提供Jinja 2模板引擎来渲染模板的同时,还可以将程序中的参数或变量值传递给指定的模板进行渲染。

templates文件夹下的index.html配置如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"><!-- 设置网页编码-->
    <title>这是首页</title><!-- 设置网页标题-->
    <h1>这是首页文字</h1><!-- 设置H1标题-->
</head>
<body>
</body>
</html>

templates文件夹下的user.html配置如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"><!-- 设置网页编码-->
    <title>这是用户中心</title><!-- 设置网页标题-->
    <h1>欢迎您:{{ name }}</h1><!-- 设置h1标题-->
</head>
<body>
</body>
</html>

app.py配置如下:

# 导入flask模块
from flask import Flask
# 导入render_template模块
from flask import render_template

# Flask初始化
app = Flask(__name__)
# 定义根路由
@app.route("/")

# 定义视图函数
def index():
    # 使用render_template()方法渲染模板
    return render_template("index.html")

#定义路由,实践时比如/user/yjg
@app.route("/user/<username>")
#定义视图函数
def user(username):
    # 使用render_template()方法渲染模板并向模板传递参数
    return render_template("user.html",name = username)

# 当直接执行该模块时,条件为真,执行代码块;当该模块被其他模块调用时,不执行代码块
if __name__ == '__main__':
    app.run(debug = True)

运行程序,得到如图所示结果。
在这里插入图片描述
render_template()函数第一个参数是指定模板文件的名称,比如这里的index.html和user.html。render_template()函数的第二个参数为可选项,可以为空。比如index()视图函数中的render_template(‘index.html’),这里第二个参数为空。第二个参数不为空的话,一般用于向模板中传递变量。这里传递变量,一般是以键值对方式进行的。

def index():
    title = "python的键值对"
    author = "CSDN_Keegan"
    # 使用render_template()方法渲染模板
    return render_template("index.html",var1 = title,var2 = author)

用上述代码替换index()视图函数代码,在index.html的和区域增加下面的代码:

<body>
<p>传过来的标题是:{{ var1 }}</p><!-- 文字原样输出-->
<br>{#br表示网页中的回车#}
<p>传过来的作者是:{{ var2 }}</p>
</body>

在这里插入图片描述
模板中接收变量值,需要把变量放在{{}},比如{{var1}}等。模板中如果要写注释,格式为{##},比如这里的{#br表示网页中的回车#}。

如果视图函数中有多个变量值都需要传递给模板该怎么办呢?
可以使用**locals()方法,例如:

def index():
    title = "python的键值对"
    author = "CSDN_Keegan"
    # 使用render_template()方法渲染模板
    return render_template("index.html",**locals())

实际上是将 return render_template(‘index.html’,var1=title,var2=author)这行代码替换为
return render_template(‘index.html’,**locals())。
将模板文件index.html中的{{var1}}
{{var2}}替换为{{title}}
{{author}}即可。

<body>
<p>传过来的标题是:{{ title }}</p><!-- 文字原样输出-->
<br><!--br表示网页中的回车 -->
{#br表示网页中的回车#}
<p>传过来的作者是:{{ author }}</p>
</body>

在这里插入图片描述
**注意:在render_template()函数中,如果要给模板传递【全部】的本地变量,可以使用【locals()】方法,此时,在模块中可以直接使用{{title}}和{{author}}来直接使用变量。

3.3 模板中控制语句之if语句

在Jinja 2模板引擎中也可以使用if和for循环控制语句,控制模板渲染的方向。模板引擎中,if和for语句中应该放到{%%}中。

index.html

<!DOCTYPE html><!---->
<html lang="en">
<head>
    <meta charset="UTF-8"><!--设定网页编码-->
    <title>Title</title><!--设定网页标题-->
</head>
<body>
{% if name %}<!--name值是否存在-->
<h1>产生的随机数有效!</h1><!--如果是存在的,则输出这句话-->
{% else %}<!--如果是不存在的-->
<h1>产生的随机数无效</h1>
{% endif %}<!--结束if-->
</body>
</html>

app.py

# 导入Flask及render_template模块
from flask import Flask,render_template
# 导入random模块
import random

# Flask初始化
app = Flask(__name__)

# 定义路由
@app.route('/')
# 定义视图函数
def hello_world():
    # 产生0-1之间的整数
    rand1 = random.randint(0,1)
    return render_template("index.html",name = rand1)


if __name__ == '__main__':
    app.run(debug=True)

在这里插入图片描述
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% if name == 1 %}
<h1>恭喜,你获得了一等奖</h1>
{% elif name == 2 %}
<h1>恭喜,你获得了二等奖</h1>
{% else %}
<h1>恭喜,抽到了三等奖</h1>
{% endif %}
{{ name }}
</body>
</html>

app.py

from flask import Flask,render_template
import random

app = Flask(__name__)

@app.route('/')
def hello_world():
    rand1 = random.randint(1,3)
    return render_template("index.html",name = rand1)

if __name__ == '__main__':
    app.run(debug=True)

在这里插入图片描述
在模板中,尽量少使用多层嵌套的if…else…语句,往往会因为缩进出现这样或那样的问题。尽量多用if…elif…else…的结构(即多个elif),这一系列条件判断会从上到下依次判断,如果某个判断为True,执行完对应的代码块,后面的条件判断就会直接忽略,不再执行。

注意:模板的表达式都是包含在分隔符”{{}}”内的;控制语句都是包含在分隔符”{%%}”内的;模板中的注释是放在包含在分隔符”{##}”内,支持块注释。

3.4 模板中控制语句之for语句

for循环语句是Python中的一个循环控制语句,任何有序的序列对象内的元素都可以遍历,比如字符串、列表、元组等可迭代对像。for循环的语法格式如下:
在这里插入图片描述
shop.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table>
    <thead>
    <th>商品名称</th>
    <th>商品价格</th>
    </thead>
    <tbody>
    <meta charset="UTF-8">
    {% for goods in goods %}
        <tr>
            <td>{{ goods.name }}</td>
            <td>{{ goods.price }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>
</body>
</html>

app.py

from flask import Flask,render_template

app = Flask(__name__)


@app.route('/')
def hello_world():
    goods = [{"name":"阳光男孩外套春秋韩版宽松2020新款上市","price":149.00},
             {"name":"黑色时尚外套女春秋版2020新款韩版休闲","price":100.00},
             {"name":"复古牛仔外套男2020新款","price":136.00},
             {"name":"新百伦耐穿2020新款","price":265.00}]
    return render_template("shop.html",**locals())


if __name__ == '__main__':
    app.run(debug=True)

在这里插入图片描述
注意:在模板中,使用if条件判断语句或者是for循环语句可以帮助开发者更好地渲染模板。通过{%逻辑表达式%}可以实现代码的嵌套,其语法与Python语法基本一致,但是必须要包含在{%%}内部。

3.5 Flask的过滤器

过滤器本质上是一个转换函数,有时候我们不仅需要输出变量的值,还需要把某个变量的值修改后再显示出来,而在模板中不能直接调用Python中的某些方法,这么这就用到了过滤器。

3.5.1 常见的过滤器

1.与字符串操作相关的过滤器
2.对列表进行操作相关的过滤器
3.对数值进行操作相关的过滤器
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>过滤器</title>
</head>
<body>
<p>{{ age|abs }}</p>
<p>{{ "hello"|capitalize }}</p>
<p>{{ "hello"|replace("h","x") }}</p>
<p>{{ [01,80,42,44,77]|first }}</p>
<p>{{ [01,80,42,44,77]|last }}</p>
<p>{{ [01,80,42,44,77]|count }}</p>
<p>{{ [01,80,42,44,77]|sort }}</p>
<p>{{ [01,80,42,44,77]|join(",")}}</p>
<p>{{ 18.888|round(2,"floor")}}</p>
<p>{{ 18.888|round }}</p>
<p>{{ -2|abs }}</p>
</body>
</html>

app.py

from flask import Flask,render_template

app = Flask(__name__)


@app.route('/')
def hello_world():
    student = {
        "name":"keegan",
        "age":-18
    }
    return render_template("index.html",**student)


if __name__ == '__main__':
    app.run()

在这里插入图片描述

3.5.2 自定义过滤器

过滤器的实质就是一个转换函数,我们其实完全可以写出属于自己的自定义过滤器。通过调用应用程序实例的add_template_filter方法实现自定义过滤器。该方法第一个参数是函数名,第二个参数是自定义的过滤器名称。
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .line{
            display: inline-block;
            height: 1px;
            width: 100%;
            background: #00CCFF;
            overflow: hidden;
            vertical-align: middle;
        }
    </style>
</head>
<body>
<meta charset="UTF-8">
{%  for goods in goods %}
{#对列表进行遍历#}
    <li style = "list-style-type:none">{{ goods.name }}
        <span class = "{{ loop.index |  index_class}}"></span>
    </li>
{% endfor %}
</body>
</html>

上面的代码对传递过来的列表进行遍历,每3行输出一条分割线,分割线的样式见style里的代码。
app.py

from flask import Flask,render_template
import sys
app = Flask(__name__)

@app.route('/')
def hello_world():
    ### 定义商品列表goods
    goods = [{"name":"三国痣"},
             {"name":"y语言核心编程"},
             {"name":"阿里巴巴和四十大盗"},
             {"name":"荣耀25 pro"}]
    return render_template("index.html",**locals())

def do_index_class(index):
    ### 每个三行输出输出line
    if index % 3 == 0:
        return "line"

### 使用自定义过滤器添加CSS
app.add_template_filter(do_index_class,"index_class")

if __name__ == '__main__':
    app.run()


在这里插入图片描述

3.6 宏是什么及使用

Jinja 2中的宏功能有些类似于传统程序语言中的函数,它跟Python中的函数类似,可以传递参数,但是【不能】有返回值,可以将一些经【常用】到的代码片段放到【宏】中,然后把一些【不固定】的值抽取出来作为一个【变量】。

3.6.1 宏是什么?

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>宏的定义和使用</title>

</head>
<body>
{#宏的定义#}
{% macro input(name,type="text",value = "") -%}
<input type="{{ type }}" name = "{{ name }}" value = "{{ value }}">
{%- endmacro %}

{#宏的使用#}
<div style = "color:#0000FF">
    <p>用户名:{{ input("username") }}</p>
    <p>密码:{{ input("password",type = "password") }}</p>
    <p>登录:{{ input("submit",type = "submit",value = "登录") }}</p>
</div>
</body>
</html>

app.py

from flask import Flask,render_template

app = Flask(__name__)


@app.route('/')
def hello_world():
    return render_template("index.html")

if __name__ == '__main__':
    app.run(debug=True)

在这里插入图片描述
注意:上面将input标签定义成了一个宏,根据实际情况,还可以在宏的定义中加入size和placeholder等属性,如{%macro input(name,type='text',value='',size=20,placeholder="请在这里输入用户名")-%}。<input type="{{type}}"name="{{name}}"value="{{value}}"size="{{size}}",placeholder="{{placeholder}}">

3.6.2 宏的导入

一个宏可以被不同的模板使用,所以我们建议将其声明在一个单独的模板文件中。需要使用时导入即可,而导入的方法类似于Python中的import。

form.html

{% macro input(name,type = "text",value = "") -%}
    <input type = "{{ type }}" name = "{{ name }}" value = "{{ value|e }}">
{%- endmacro %}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>宏的导入</title>
</head>
<body>
{% import "form.html" as form %}
{#导入宏#}
<div style = "color:#0000FF"></div>
{#使用宏定义用户名输入框#}
<p>用户名:{{ form.input("username") }}</p>
{#使用宏定义输入密码输入框#}
<p>密码:{{ form.input("password",type = "password" )}}</p>
<p>登录:{{ form.input("submit",type = "submit",value = "登录") }}</p>
</body>
</html>

app.py

from flask import Flask,render_template

app = Flask(__name__)


@app.route('/')
def hello_world():
    return render_template("index.html")

if __name__ == '__main__':
    app.run()

在这里插入图片描述
注意:{%import’form.html’as form%}这种导入方法也可以使用{%from’form.html’importinput%}实现导入。

用户名:{{form.input(‘username’)}}

中的form需要去掉了,直接写成

用户名:{{input(‘username’)}}

3.6.3 include的使用

宏文件中引用其他宏,可以使用include语句。include语句可以把一个模板引入到另外一个模板中,类似于把一个模板的代码复制到另外一个模板的指定位置。
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        .header{
            width:100%;
            height:40px;
            margin: 20px 20px;
        }
        .footer{
            width:100%;
            height:40px;
            margin: 20px 20px;
        }
        .content{
            width:100%;
            heigth:40px;
            margin: 20px 20px;
        }
    </style>
</head>
<body>
{% include "header.html" %}
<div class = "content">
这是网页内容
</div>
{% include "footer.html" %}
</body>
</html>

header.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<div class = "header">
    这是网页头部
</div>
<body>

</body>
</html>

footer.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class = "footer">
    这是网页尾部
</div>
</body>
</html>

在这里插入图片描述

include把一个模板的代码复制到另外一个模板的指定位置,这里的{%include''header.html''%}和{%include''footer.html''%}把头文件和尾部文件引入到index.html文件中。
注意:使用include标签时是在templates目录中寻找相应的文件,不要使用相对路径。

3.7 set和with语句的使用

set与with语句都可以在Jinja 2中定义变量并赋予值。set定义的变量在整个模板范围内都有效,with关键字在定义变量并赋值的同时,限制了with定义变量的作用范围。
index.py

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<br>
{#给变量赋值#}
{% set telephone = "1388888888" %}
{#给列表或数组赋值#}
{% set nav = [("index.html","index"),("product.html","product")] %}
{{ telephone }}
<br>
{{ nav }}
<br>
{#with定义的变量的作用范围在{%with%}和{%endwith%}代码块内,在模板的其他地方,引用此变量值无效。#}
{% with pass = 60 %}
{{ pass }}
{% endwith %}
<body>

</body>
</html>

app.py

from flask import Flask,render_template

app = Flask(__name__)


@app.route('/')
def hello_world():
    return render_template("index.html")

if __name__ == '__main__':
    app.run(debug=True)

在这里插入图片描述

3.8 静态文件的加载

静态文件的加载一般需要先新建文件夹static,在文件夹下再新建css、js和images文件夹,在这些文件夹中存放css、js、images,同时要需要使用url_for函数。

项目目录结构:
在这里插入图片描述
在templates目录下新建一个名为index.html的文件,在app.py的视图函数中使用returnrender_template(‘index.html’)方法来渲染模板。下面分别给出加载JS、图片和CSS的方法。
(1)加载JS文件在静态文件index.html中,在之前引入jquery-3.4.1.js文件,具体代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {#   加载JS文件#}
      <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    </script>
</head>
<body>
</body>
</html>

(2)加载图片文件。

 <img src="{{ url_for("static",filename = "images/a.jpg")}}"></img>

(3)加载CSS文件。加载外部CSS文件,可以使用下述代码实现:

{#   加载CSS文件#}
    <link rel="stylesheet" href="{{ url_for("static",filename = "css/a.css") }}">

a.css

.img{
    BORDER-RIGHT: #000 1px solid;BORDER-TOP: #000 1px solid; MARGIN: 10px 0px;
    BORDER-LEFT: #000 1px solid;BORDER-BOTTOM: #000 1px solid
}

总代码:
a.css

.img{
    BORDER-RIGHT: #000 1px solid;BORDER-TOP: #000 1px solid; MARGIN: 10px 0px;
    BORDER-LEFT: #000 1px solid;BORDER-BOTTOM: #000 1px solid
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
{#   加载JS文件#}
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
{#   加载CSS文件#}
    <link rel="stylesheet" href="{{ url_for("static",filename = "css/a.css") }}">
</head>
<body>
{#
测试jQuery是否加载
#}
<script>
    if(jQuery){
        alert("jQuery已加载");
    }
    else{
        alert("jQuery未加载")
    }
</script>
<div class = "img">
    <img src="{{ url_for("static",filename = "images/a.jpg")}}"></img>
     加载图片
</div>
</body>
</html>

app.py

from flask import Flask,render_template
app = Flask(__name__)

@app.route('/')
def hello_world():
    return render_template("index.html")

if __name__ == '__main__':
    app.run(debug=True)

运行结果:
在这里插入图片描述

3.9 模板的继承

一个系统网站往往需要统一的结构,这样看起来比较“整洁”。比如,一个页面中都有标题、内容显示、底部等几个部分。如果在每一个网页中都进行这几部分的编写,那么整个网站将会有很多冗余部分,而且编写的网页程序也不美观。这时可以采用模板继承,即将相同的部分提取出来,形成一个base.html,具有这些相同部分的网页通过继承base.html来得到对应的模块。
1.模板的继承语法模板的继承语法如下:
在这里插入图片描述

在templates目录中创建index.html、base.html和product.html 3个静态文件。base.html文件作为基类,index.html和product.html文件作为子类,子类去继承基类的基本内容。

目录结构:
在这里插入图片描述

base.html文件内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %} -我的网站</title>
</head>
<body>
{% block body %}
这是基类里的内容
{% endblock %}
</body>
</html>

index.html文件内容如下:

{% extends "base.html" %}
{% block title %}网站首页{% endblock %}
{% block body %}
    {{ super() }}
<h4>这是网站首页的内容</h4>
{% endblock %}

product.html文件的内容:

{% extends "base.html" %}
{% block title %} 产品列表页{% endblock %}
{% block body %}
<h4>这是产品列表页的内容</h4>
取得网页标题的内容:
<h4>{{ self.title() }}</h4>
{% endblock %}

app.py文件内容如下:

from flask import Flask,render_template

app = Flask(__name__)


@app.route('/')
def index():
    return render_template("index.html")

@app.route("/product")
def product():
    return render_template("product.html")


if __name__ == '__main__':
    app.run(debug = True)

默认情况下,子模板如果实现了父模板定义的block,那么子模板block中的代码就会覆盖父模板中的代码。如果想要在子模板中仍然保持父摸板中的代码,那么可以使用{{super()}}来实现,如index.html中{%block body%}{%endblock%}代码块中使用了{{super()}}方法,运行结果如图所示:
在这里插入图片描述
如果想要在一个block中调用其他block中的代码,可以通过{{self.其他block名称()}}实现。比如product.html文件中的

{{self.title()}}

方法。运行此代码,结果如图所示。
在这里插入图片描述
注意:模板的继承可以这么理解:就是在一个html文档中已经写好了框架,然后要往里面放东西时,先用<%block blockname%><%endblock%>放一个空的块在里面作为基础模块,接下来被别的子模块导入的时候,用子模块里相同名称的模块替代。
例如:
在这里插入图片描述

发布了512 篇原创文章 · 获赞 839 · 访问量 27万+

猜你喜欢

转载自blog.csdn.net/YJG7D314/article/details/105122551