Django模板层

【一】Django框架之生命周期流程图

【二】模板语法的传值

【1】视图层语法

  • 变量命名包括任意数字、字母以及下划线
    • 不能包含空格或者标点符号

(1)方式1

  • 通过字典传值到模板层
    • 将需要传递给模板的数据作为字典的键值对,然后将该字典作为第三个参数传递给 render 函数。
python 复制代码
from django.shortcuts import render

def index(request):
    data_dict = {
        'name': 'bruce',
        'age': 18,
    }
    password = "000"
    return render(request, 'index.html', data_dict)
  • 只将字典内的键值对传递给模型层前端页面
    • 在这个列子中的password前端端是取不到的

(2)方式二

  • 通过 locals() 方法传值到模板层
    • 它会返回当前作用域中的所有局部变量作为字典
python 复制代码
def index(request):
    data_dict = {
        'name': 'bruce',
        'age': 18,
    }
    password = "000"
    return render(request, 'index.html', locals())
  • 模型层前端页面将拿到所有定义的局部变量

【2】基本数据类型

python 复制代码
def index(request):
    # 整型int
    int1 = 18
    # 浮点型float
    float1 = 12.00
    float2 = 15.99
    # 字符串str
    str1 = "秦始皇"
    # 布尔型bool
    bool1 = True
    # 列表list
    list1 = [11, 22, 33]
    # 字典dict
    dict1 = {"name": "秦始皇", "age": 1000}
    # 元组tuple
    tuple1 = (11,)
    # 集合set
    set1 = {'tom', "Tom"}
    return render(request, 'index.html', locals())
  • 前端页面index.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    {% load static %}
    <script src="{% static 'js/jquery-3.5.1.min.js' %}"></script>
    <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>

</head>
<body>
<p> 整型 18 --> {{ int1 }}</p>
<p> 浮点型 12.00 --> {{ float1 }}</p>
<p> 浮点型 15.99 --> {{ float2 }}</p>
<p> 字符串 "秦始皇" --> {{ str1 }}</p>
<p> 布尔型 True --> {{ bool1 }}</p>
<p> 列表 [11, 22, 33] --> {{ list1 }}</p>
<p> 字典 {"name": "秦始皇", "age": 1000} --> {{ dict1 }}</p>
<p> 元组 (11,) --> {{ tuple1 }}</p>
<p> 集合 {'tom', "Tom"} --> {{ set1 }}</p>
</body>
</html>
  • 显示结果
python 复制代码
整型 18 --> 18
浮点型 12.00 --> 12.0
浮点型 15.99 --> 15.99
字符串 "秦始皇" --> 秦始皇
布尔型 True --> True
列表 [11, 22, 33] --> [11, 22, 33]
字典 {"name": "秦始皇", "age": 1000} --> {'name': '秦始皇', 'age': 1000}
元组 (11,) --> (11,)
集合 {'tom', "Tom"} --> {'tom', 'Tom'}

【3】函数和类

(1)函数

  • 结论
    • 有返回值的可以显示返回值
    • 没有返回值的只显示None
  • 视图函数
python 复制代码
def index(request):
    # 没有返回值函数
    def func1():
        pass
	# 有返回值函数
    def func2():
        name = "秦始皇"
        return name
    return render(request, 'index.html', locals())
  • 前端页面
html 复制代码
<p> 函数没有返回值 --> {{ func1 }}</p>
<p> 函数有返回值 --> {{ func2 }}</p>
  • 结果
python 复制代码
函数没有返回值 --> None
函数有返回值 --> 秦始皇

(2)类

  • 结论:

    • 方法有返回值就是返回值
    • 有魔法方法__str__,能用就用
    • 有魔法方法__call__
      • 注意:方法将无法直接调用,需要先在视图函数中执行
  • 视图函数

python 复制代码
def index(request):
    # 类没有__str__和__call__
    class Class1(object):
        @staticmethod
        def introduce():
            name = "秦始皇"
            return f"我是{name},V我50"
    class1 = Class1()

    # 类有__str__
    class Class2(object):
        @staticmethod
        def introduce():
            name = "秦始皇"
            return f"我是{name},V我50"

        def __str__(self):
            return "被print了"
    class2 = Class2()

    # 类有__call__
    class Class3(object):
        @staticmethod
        def introduce():
            name = "秦始皇"
            return f"我是{name},V我50"

        def __call__(self, *args, **kwargs):
            return "实例加括号了"

    class3 = Class3()

    # 类同时有__call__和__str__
    class Class4(object):
        @staticmethod
        def introduce():
            name = "秦始皇"
            return f"我是{name},V我50"

        def __str__(self):
            return "被print了"


        def __call__(self, *args, **kwargs):
            return "实例加括号了"
    class4 = Class4()

    return render(request, 'index.html', locals())
  • 前端页面
html 复制代码
<h3>类没有__str__和__call__</h3>
<p> 类 --> {{ Class1 }}</p>
<p> 实例 --> {{ class1 }}</p>
<p> 方法--> {{ class1.introduce }}</p>
<h3>类有__str__</h3>
<p> 类 --> {{ Class2 }}</p>
<p> 实例 --> {{ class2 }}</p>
<p> 方法--> {{ class2.introduce }}</p>
<h3>类有__call__</h3>
<p> 类 --> {{ Class3 }}</p>
<p> 实例 --> {{ class3 }}</p>
<p> 方法--> {{ class3.introduce}}</p>
<h3>类同时有__str__和__call__</h3>
<p> 类 --> {{ Class4 }}</p>
<p> 实例 --> {{ class4 }}</p>
<p> 方法--> {{ class4.introduce }}</p>
  • 结果
python 复制代码
类没有__str__和__call__
类 --> <app01.views.index.<locals>.Class1 object at 0x00000170AAFC4F10>
实例 --> <app01.views.index.<locals>.Class1 object at 0x00000170AB310D60>
方法--> 我是秦始皇,V我50

类有__str__
类 --> 被print了
实例 --> 被print了
方法--> 我是秦始皇,V我50

类有__call__
类 --> <app01.views.index.<locals>.Class3 object at 0x00000170AAFC55D0>
实例 --> 实例加括号了
方法-->

类同时有__str__和__call__
类 --> 被print了
实例 --> 实例加括号了
方法-->

【三】模板语法的取值

【1】模板层语法

(1)变量相关

  • 变量输出:使用双大括号 {``{ 变量名 }} 来输出变量的值。
html 复制代码
<p>My name is {{ name }}</p>
  • 变量过滤器:可以在变量输出中使用过滤器来对变量进行处理。过滤器使用管道符 | 进行连接。
html 复制代码
<p>My age is {{ age|default:"Unknown" }}</p>
  • 变量属性:可以通过点号 . 来访问变量的属性。
html 复制代码
<p>My favorite color is {{ person.favorite_color }}</p>

(2)逻辑相关

  • 条件语句
    • 使用 {% if 条件 %}...{% endif %} 来进行条件判断。
html 复制代码
{% if age >= 18 %}
    <p>You are an adult.</p>
{% else %}
    <p>You are not an adult.</p>
{% endif %}
  • 循环语句
    • 使用 {% for 变量 in 列表 %}...{% endfor %} 来进行循环操作。
html 复制代码
<ul>
{% for item in items %}
    <li>{{ item }}</li>
{% endfor %}
</ul>
  • 注释
    • 使用 {# 注释内容 #} 来添加注释,注释内容不会被渲染到最终的 HTML 页面中。
html 复制代码
{# This is a comment. #}

【2】复杂数据类型取值

(1)基本数据类型组合

  • Django模板语法的取值是固定的

    • 只能用.取值,包括列表
    • 不支持负数索引
  • 视图层

python 复制代码
def index(request):
    example1 = {"name": "秦始皇", "servant": ['p1', 'p2', 'p3'], }
    return render(request, 'index.html', locals())
  • 前端页面
html 复制代码
<p>字典中的值 --> {{ example1.name }}</p>
<p>字符串的第一个元素 --> {{ example1.name.0 }}</p>
<p>字典中的列表 --> {{ example1.servant }}</p>
<p>列表中的第二个元素 --> {{ example1.servant.1 }}</p>
  • 结果
python 复制代码
字典中的值 --> 秦始皇
字符串的第一个元素 --> 秦

字典中的列表 --> ['p1', 'p2', 'p3']
列表中的第二个元素 --> p2

(2)字典

  • 字典类型还是支持
    • .keys.values.items
dj 复制代码
# 视图
user_dict = {"name": 'bruce', "age": 18, "hobby": ['basketball', 'badminton']}

# 模板层
<p> 字典keys --> {{ user_dict.keys }}</p>
<p> 字典values --> {{ user_dict.values }}</p>
<p> 字典items --> {{ user_dict.items }}</p>

# 结果
字典keys --> dict_keys(['name', 'age', 'hobby'])
字典values --> dict_values(['bruce', 18, ['basketball', 'badminton']])
字典items --> dict_items([('name', 'bruce'), ('age', 18), ('hobby', ['basketball', 'badminton'])])

【3】过滤器(filter)

  • 理解为Python中基础数据类型的内置方法

(1)语法

html 复制代码
{{ value|filter_name:参数 }}
{{数据|过滤器:参数}}
  • 注意
    • 使用管道符号"|"连接
    • 管道符号两侧没有空格
    • 最多支持两个参数
    • 支持链式操作

(2)长度

  • 语法
html 复制代码
{{ value|length }}
  • 将返回value的长度

(3)默认值

  • 如果一个变量值为False,或者为空,则使用默认值

  • 语法

html 复制代码
{{ value|default:"nothing"}}
  • 示例
python 复制代码
# 视图
flag = False
str1 = ""
    
# 前端
<p>{{ flag|default:"啥也没有" }}</p>
<p>{{ str1|default:"啥也没有" }}</p>

# 结果
啥也没有
啥也没有

(4)文件大小

  • 语法
html 复制代码
{{ value|filesizeformat}}
  • 将后端计算的得到的文件大小
    • 可以是字符串也可以是浮点型
  • 经过文件大小(1024)的转换显示单位的结果
  • 示例
python 复制代码
# 视图
size1 = "1024"
size2 = 112562.5

# 前端
<p>{{ size1|filesizeformat }}</p>
<p>{{ size2|filesizeformat }}</p>

# 结果
1.0 KB
109.9 KB

(5)日期格式化

  • 语法
html 复制代码
{{ value|date:"格式"}}
格式化字符 描述 示例输出
a 'a.m.''p.m.'(请注意,这与PHP的输出略有不同,因为这包括符合Associated Press风格的期间) 'a.m.'
A 'AM''PM' 'AM'
b 月,文字,3个字母,小写。 'jan'
B 未实现。
c ISO 8601格式。 (注意:与其他格式化程序不同,例如"Z","O"或"r",如果值为naive datetime,则"c"格式化程序不会添加时区偏移量(请参阅datetime.tzinfo) 。 2008-01-02T10:30:00.000123+02:002008-01-02T10:30:00.000123如果datetime是天真的
d 月的日子,带前导零的2位数字。 '01''31'
D 一周中的文字,3个字母。 "星期五"
e 时区名称 可能是任何格式,或者可能返回一个空字符串,具体取决于datetime。 '''GMT''-500''US/Eastern'
E 月份,特定地区的替代表示通常用于长日期表示。 'listopada'(对于波兰语区域,而不是'Listopad'
f 时间,在12小时的小时和分钟内,如果它们为零,则分钟停留。 专有扩展。 '1''1:30'
F 月,文,长。 '一月'
g 小时,12小时格式,无前导零。 '1''12'
G 小时,24小时格式,无前导零。 '0''23'
h 小时,12小时格式。 '01''12'
H 小时,24小时格式。 '00''23'
i 分钟。 '00''59'
I 夏令时间,无论是否生效。 '1''0'
j 没有前导零的月份的日子。 '1''31'
l 星期几,文字长。 '星期五'
L 布尔值是否是一个闰年。 TrueFalse
m 月,2位数字带前导零。 '01''12'
M 月,文字,3个字母。 "扬"
n 月无前导零。 '1''12'
N 美联社风格的月份缩写。 专有扩展。 'Jan.''Feb.''March''May'
o ISO-8601周编号,对应于使用闰年的ISO-8601周数(W)。 对于更常见的年份格式,请参见Y。 '1999年'
O 与格林威治时间的差异在几小时内。 '+0200'
P 时间为12小时,分钟和'a.m。'/'p.m。',如果为零,分钟停留,特殊情况下的字符串"午夜"和"中午"。 专有扩展。 '1 am''1:30 pm' / t3>,'midnight','noon','12:30 pm' / T10>
r RFC 5322格式化日期。 'Thu, 21 Dec 2000 16:01:07 +0200'
s 秒,带前导零的2位数字。 '00''59'
S 一个月的英文序数后缀,2个字符。 'st''nd''rd''th'
t 给定月份的天数。 28 to 31
T 本机的时区。 'EST''MDT'
u 微秒。 000000 to 999999
U 自Unix Epoch以来的二分之一(1970年1月1日00:00:00 UTC)。
w 星期几,数字无前导零。 '0'(星期日)至'6'(星期六)
W ISO-8601周数,周数从星期一开始。 153
y 年份,2位数字。 '99'
Y 年,4位数。 '1999年'
z 一年中的日子 0365
Z 时区偏移量,单位为秒。 UTC以西时区的偏移量总是为负数,对于UTC以东时,它们总是为正。 -4320043200
  • 示例
python 复制代码
# 视图
current_time = datetime.datetime.now()

# 前端
<p>{{ current_time|date:'Y-m-d H:i:s' }}</p>

# 结果
2024-03-01 17:27:14

(6)切片

  • 语法
    • 支持负数
html 复制代码
{{ value|slice:""}}
  • 示例
python 复制代码
# 视图
introduce = "我是秦始皇,v我50"

# 前端
<p>{{ introduce|slice:"2:5" }}</p>
<p>{{ introduce|slice:"::-1" }}</p>

# 结果
秦始皇
05我v,皇始秦是我

(7)切取摘要

  • 语法
    • 字符串切取按照字符来
    • 单词切分按照空格来
html 复制代码
# 字符串
{{ value|truncatechars:长度}}
# 单词
{{ value|truncatewords:长度}}
  • 示例
python 复制代码
# 视图
    essay_c = "人类文明可能发生技术突变的领域有:物理学、生物学、计算机科学、寻找外星文明。其中寻找外星文明是所有技术领域中变数最大的,一旦发生,其影响力将超过另外三个领域的总和。"
    essay_e = "The fields where technological mutations may occur in human civilization are: physics, biology, computer science, and the search for extraterrestrial civilizations. The search for extraterrestrial civilizations is the most variable of all technological fields, and once it happens, its influence will exceed that of the other three fields combined."
 

# 前端
<p>{{ essay_c|truncatechars:10}}</p>
<p>{{ essay_e|truncatewords:6}}</p>

# 结果
人类文明可能发生技...
The fields where technological mutations may ...

(8)移除字符串

  • 语法
    • 类似于Python字符串的strip方法
    • strip只能去除开头和结尾,还有多个字符的区别
html 复制代码
{{ value|cut:'指定字符' }}
  • 示例
python 复制代码
# 视图
introduce = 'my name is lily, my age is 18'

# 前端
<p>{{ introduce|cut:" "}}</p>
<p>{{ introduce|cut:"i"|cut:"a"}}</p>

# 结果
mynameislily,myageis18
my nme s lly, my ge s 18

(9)拼接字符

  • 语法
    • 有类型的自动转换
    • 整型列表也可以拼接
html 复制代码
{{ value|join:"插入字符" }}
  • 示例
python 复制代码
# 视图
str_list = ["my", "name", "is", "bruce"]
int_list = [11, 22, 33]

# 前端
<p>{{ str_list|join:" "}}</p>
<p>{{ int_list|join:"-"}}</p>

# 结果
my name is bruce
11-22-33

(10)加法

  • 语法
    • 要么整型加整型(浮点型会被类型强转)
    • 要么字符串加字符串
html 复制代码
{{ value|add:整型|字符串 }}
  • 示例
python 复制代码
# 视图
str1 = 'aa'
int1 = 100.25

# 前端
<p>{{ str1|add:"bb"}}</p>
<p>{{ int1|add:99}}</p>
<p>{{ int1|add:15.25}}</p>

# 结果
aabb
199
115

(11)转义

  • 前端转义
python 复制代码
{{ value|safe }}
  • 后端转义
python 复制代码
from django.utils.safestring import mark_safe
mark_safe(value)
  • 示例
python 复制代码
# 视图
from django.utils.safestring import mark_safe
def index(request):
    msg = "<h1>我是秦始皇</h1>"
    msg_safe = mark_safe(msg)
    return render(request, 'index.html', locals())


# 前端
<p>未转义{{ msg }}</p>
<p>前端转义 {{ msg_safe}}</p>
<p>后端转义 {{ msg|safe}}</p>

# 结果
未转义<h1>我是秦始皇</h1>

前端转义

我是秦始皇
后端转义

我是秦始皇

(12)timesince

  • 语法
    • 计算time2和time1的差值
    • time2比time1小的话,将返回0 minutes
    • 如果不写time2那么time2就是当前时间
    • 差额在年以上显示年月,在月以下显示周天
    • 差额最小单位是分钟
python 复制代码
{{ time1|timesince:time2 }}
  • 示例
python 复制代码
# 视图
time1 = datetime.datetime(2018, 7, 20, 18,0)
time2 = datetime.datetime(2018, 8, 1, 19, 58)

# 前端
<p> {{ time1|timesince}}</p>
<p> {{ time1|timesince:time2}}</p>

# 结果
2 years, 7 months
1 week, 5 days

(13)timeuntil

  • 语法
    • 和timesince相反,time1是大的时间
dj 复制代码
{{ time1|timesince:time2 }}
  • 示例
python 复制代码
# 视图
time1 = datetime.datetime(2020, 7, 20, 18,0)
time2 = datetime.datetime(2018, 8, 1, 19, 58)


# 前端
<p> {{ time1|timeuntil}}</p>
<p> {{ time1|timeuntil:time2}}</p>

# 结果
0 minutes
1 year, 11 months

【4】标签(tags)

  • 理解为流程控制语句

(1)for循环

  • 语法
django 复制代码
{% for 取值 in 可遍历类型 %}
    {{# 循环操作}}
{% endfor %}
python 复制代码
# 如果可遍历类型为空才执行
{% for 取值 in 可遍历类型 %}
    # 循环操作
{% empty %}
    # 整体为空才执行
{% endfor %}
  • 一些参数
Variable Description
forloop.counter 当前循环的索引值(从1开始)
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环
  • 示例
python 复制代码
# 视图
name_list = ["bruce", "tom", "lily"]
empty_list = []

# 前端
<ul>
    {% for foo in name_list %}
        <li>{{ forloop.counter }}:{{ foo }}</li>
    {% empty %}
        <li>nothing</li>
    {% endfor %}
</ul>


<ul>
    {% for foo in empty_list %}
        <li>{{ forloop.counter }}:{{ foo }}</li>
    {% empty %}
        <li>nothing</li>
    {% endfor %}
</ul>

# 结果
•1:bruce
•2:tom
•3:lily
    
•nothing

(2)if

  • 语法

    • 注意:表达式不支持连续的判断

    dj 复制代码
    # 不支持
    {% if a>b>c %}
python 复制代码
{% if 条件表达式 %}
	# 条件成立执行  
{% elif 条件表达式 %}
	# 条件成立执行
{% else %}
  	# 都不成立执行
{% endif %}

(3)with

  • 语法
    • 简单理解为起别名
    • 注意等号左右不能有空格
python 复制代码
{% with 别名=复杂的变量 %}
或
{% with 复杂的变量 as 别名 %}

(4)csrf_token

  • 用于跨站请求伪造保护

  • 常用于form表单中

  • 默认情况下,Django 的中间件会自动对所有 POST 请求进行 CSRF 令牌验证

dj 复制代码
<form method="post">
    {% csrf_token %}
    <!-- 其他表单字段 -->
    <input type="submit" value="Submit">
</form>

(5)注释

  • 注释
dj 复制代码
{# 注释内容 #}

【5】自定义

(0)基础必备步骤

  1. 在应用下创建一个templatetags文件夹

    • 名字必须是这个
  2. 在该文件夹下创建任意py文件(customize.py)

    • 文件名字任意
  3. 在该py文件内写入

    python 复制代码
    from django import template
    register = template.Library()
    • register不能写错

(1)自定义过滤器(filter)

  • 注意:过滤器最多只能有两个参数

  • 示例:

    • templatetags/customize.py文件内创建
    • filter中的name参数可以不写,那么模板层中就用函数的名字
    • 如果filter的name参数写了,那么模板层中就只能用name的参数了
python 复制代码
from django import template
register = template.Library()


# 起别名
@register.filter(name='my_upper')
def my_upper(str1: str):
    return " ".join([i[0].upper() + i.replace(i[0], '') for i in str1.split(" ")])
  • 示例
    • 在视图层,没有特殊的新要求
python 复制代码
info1 = "hello, world!"
info2 = "I love myself!"
  • 示例
    • 在模板层
    • 需要先导入自定的py文件
    • 然后就可以正常使用了
html 复制代码
{#导入自定义文件#}
{% load customize %}
<p>自定义过滤器upper --> {{ info1|my_upper }}</p>
<p>自定义过滤器upper --> {{ info2|my_upper }}</p>
  • 结果
python 复制代码
自定义过滤器my_upper --> Hello, World!
自定义过滤器my_upper --> I Love Myself!

(2)自定义标签(simple_tag)

  • 注意:没有参数个数限制

  • 示例:

    • templatetags/customize.py文件内创建
    • filter中的name参数可以不写,那么模板层中就用函数的名字
    • 如果filter的name参数写了,那么模板层中就只能用name的参数了
python 复制代码
from django import template
register = template.Library()


# 没有别名
@register.simple_tag
def add_numbers(a, b):
    return a + b
  • 示例

    • 在视图层,没有特殊的新要求
    • 视图层可以不用写
  • 示例

    • 在模板层
    • 需要先导入自定的py文件
    • 然后就可以正常使用了
html 复制代码
{#导入自定义文件#}
{% load customize %}
{% add_numbers 12 15 as res %}
The sum of 12 and 15 is: {{ res }}
  • 结果
python 复制代码
The sum of 12 and 15 is: 27

(3)自定义包含标签(inclusion_tag)

  • 作用

    • 包含标签用于渲染一个模板片段,并将结果插入到主模板中。
  • 示例

    • 在模板层templatetags下创建模板片段
    • 我的模板文件名pagination.html
html 复制代码
<nav aria-label="Page navigation">
    <ul class="pagination">
        <li>
            <a href="#" aria-label="Previous">
                <span aria-hidden="true"><<</span>
            </a>
        </li>
        {% for i in num_list %}
            <li><a href="#">{{ i }}</a></li>
        {% endfor %}
        <li>
            <a href="#" aria-label="Next">
                <span aria-hidden="true">>></span>
            </a>
        </li>
    </ul>
</nav>
  • 示例
    • 在自定义文件(templatetags/customize.py)中
    • name参数和之前一样
    • filename参数是文件模板的文件名
python 复制代码
from django import template
register = template.Library()

@register.inclusion_tag(name='mypage',filename="pagination.html")
def page(start: int, n: int):
    num_list = [i for i in range(start, start + n)]
    return locals()
  • 示例
    • 前端页面在我们需要添加模板的地方
    • 写下语句即可
html 复制代码
{#导入自定义文件#}
{% load customize %}
{% mypage 6 5 %}

【四】模板的继承

【1】介绍

  • 模板继承是Django的一个重要概念,它允许创建一个基础模板(父模板),并在其基础上创建其他模板(子模版)。
  • 子模版可以继承父模板的结构和内容,并可以覆盖或扩展其中的部分内容

【2】父模板

  • 父模板一般叫做base.html
    • 父模板中使用{% block %}标签来定义可以被子模版覆盖的内容区域
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    {% load static %}
    <script src="{% static 'js/jquery-3.5.1.min.js' %}"></script>
    <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
    {% block page-css %}
        {#页面css内容#}
    {% endblock %}
</head>
<body>
    
{% block page-main %}
{#	页面主要内容#}
{% endblock %}

{% block page-script %}
{#	页面script内容#}
{% endblock %}

</body>
</html>

【3】子模版

  • 子模版的文件名随意
    • 第一行需要使用extends标签指定父模板
    • 使用block标签书写页面内容即可
html 复制代码
{% extends 'base.html' %}

{% block page-css %}
{#	编写页面css#}
{% endblock %}

{% block page-main %}
{#    书写页面主要内容#}
{% endblock %}

{% block page-script %}
{#	编写页面script#}
{% endblock %}

【4】include

(1)说明

  • include是Django模板系统中的一个内置标签,用于在模板中包含其他模板的内容
  • 通过使用include标签,可以将一个模板中的内容嵌套到另一个模板中,实现模块化和代码重用

(2)示例

  • 模板header.html
html 复制代码
<header>
    <h1>My Website</h1>
</header>
  • 模板footer.html
html 复制代码
<footer>
    <p>© 2022 My Website. All rights reserved.</p>
</footer>
  • 模板page.html
html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>My Website</title>
</head>
<body>
    {% include 'header.html' %}
    
    <main>
        <h2>Welcome to My Website!</h2>
        <p>This is the content of the page.</p>
    </main>
    
    {% include 'footer.html' %}
</body>
</html>
  • header.htmlfooter.html 分别定义了网页的页眉和页脚部分。
  • page.html 是主模板,它使用 {% include %} 标签来包含 header.htmlfooter.html 的内容。当渲染 page.html 模板时,Django 会自动将 header.htmlfooter.html 的内容嵌入到相应的位置。

【五】静态文件加载

  • {% load static %}

【1】{% static %}

  • {% static %}是django模板系统中的一个内置标签,用于在模板中引用静态文件
    • 如css、javascript、图像等
  • 在django项目中,静态文件通常都是存储在static文件夹中。
  • 示例
    • 引用bootstrap和jquery文件
html 复制代码
{% load static %}
<script src="{% static 'js/jquery-3.5.1.min.js' %}"></script>
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
  • 示例
    • 某个文件被多处引用可以起别名
html 复制代码
{% load static %}
{% static 'image/brand.png as 别名'}

{{ ...别名... }}

【2】{% get_static_prefix %}

  • 使用这个标签可以获取到static文件夹的绝对路径

  • 示例

    • 两种导入文件的方法
    • 效果一样,推荐上面的
html 复制代码
{% load static %}

<img src="{% static 'images/brand.png' %}">
<img src="{% get_static_prefix %}images/brand.png">
相关推荐
山川而川-R11 分钟前
ubuntu22.04安装PaddleX3
python·ocr
从以前1 小时前
【算法题解】Bindian 山丘信号问题(E. Bindian Signaling)
开发语言·python·算法
kirito学长-Java1 小时前
springboot/ssm网上宠物店系统Java代码编写web宠物用品商城项目
java·spring boot·后端
海绵波波1071 小时前
flask后端开发(9):ORM模型外键+迁移ORM模型
后端·python·flask
余生H1 小时前
前端Python应用指南(二)深入Flask:理解Flask的应用结构与模块化设计
前端·后端·python·flask·全栈
CriticalThinking2 小时前
Pycharm不正常识别包含中文路径的解释器
ide·python·pycharm
AI人H哥会Java2 小时前
【Spring】基于XML的Spring容器配置——<bean>标签与属性解析
java·开发语言·spring boot·后端·架构
计算机学长felix2 小时前
基于SpringBoot的“大学生社团活动平台”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·后端