Django模板

模板的功能

控制前台页面展示的内容,包含两块:

  • 静态内容:js、css、html
  • 动态内容:模板中的一些动态代码生成的内容

模板的查找顺序

  • 首先在settings.py中配置的模板文件路径中依次进行寻找
  • 如果配置的模板文件中找不到,则到注册的应用中所对应的模板目录下进行寻找,前提是这些应用有templates目录

模板语言

模板变量

模板变量名由数字、字母、下划线和点组成,不能以下划线开头

模板标签和内建函数很多:https://docs.djangoproject.com/zh-hans/3.1/ref/templates/builtins/

模板变量的解析顺序如下(b.title):

  • 首先将b当作字典,将title当作b的键
  • 然后将b当作对象,将title当作b的属性
  • 最后将b当作对象,将title当作b的方法
  • 如果上述方法都失败,则返回空字符串

若变量格式为(b.数字):

  • 首先将b当作字典,将数字当作键
  • 然后将b当作列表,将数字当作b[数字]取值
  • 如果上述方法都失败,则返回空字符串

模板标签

  • 格式

    1
    {% 代码段 %}
  • for循环和if条件判断

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    {# 模板中的for循环 #}
    {% for num in book %}
    {# forloop-counter变量可以打印出当前循环的次数#}
    <div>{{ forloop.counter }}循环执行的语句</div>
    {% empty %}
    <div>循环对象为空时执行的语句</div>
    {% endfor %}

    {# 条件判断 #}
    {# 条件判断符:>、<、>=、<=、!=、== #}
    {# 逻辑判断:not and or #}
    {# 条件判断符两端必须保留空格,否则就会报错, {% %}包裹的是代码段,变量可直接引用 #}
    {% if num >= 2 %}
    <div>条件大于2时执行的语句</div>
    {% elif num >= 3 %}
    <div>条件大于3时执行的语句</div>
    {% else %}
    <div>所有的条件都不成立时执行的语句</div>
    {% endif %}
    </body>
    </html>

过滤器

当需要对模版变量的输出格式进行修改的时候,就需要用到过滤器,格式:【模板变量 | 过滤器: 参数】

1
2
3
# 过滤器在模板文件中使用
# date是模板的内建函数,后面的Y、m、D是其对应的参数
<li>{{ time.week|date: "Y年-m天-D天" }}</li>

自定义过滤器

当django提供的过滤器无法满足需求的时候,这个时候就需要我们自己创建过滤器,步骤如下:

  1. 在对应的应用下创建【templatetags包】

    1
    mkdir templatetags
  2. 在templatetags文件夹中创建过滤器文件【过滤器本质就是python的函数】

    1
    2
    # 名字随意
    touch usertags.py
  3. 在过滤器文件中编写过滤器函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # 引入库文件
    from django.template import Library

    # 生成Library对象
    register = Library()

    # 定义过滤器,必须用Library对象的filter方法进行装饰
    @register.filter
    # 过滤器最多传递两个参数,第一个参数是模板变量本身,另一个就是过滤器参数
    def mod(num):
    return num%2==0

    @register.filter
    def mod2(num, val):
    return num%val == 0
  4. 在模板文件中使用自定义的过滤器

    1
    2
    3
    4
    5
    6
    7
    8
    # 导入自定义的模板文件,load后面直接跟过滤器文件名称
    {% load usertags %}

    # 当过滤器只有一个参数的时候,则不用传递,它会将模板变量当作参数传递给过滤器
    <li>{{ time.week|mod}}</li>

    # 当过滤器有两个参数时,则后面只需要再传递一个参数,它会将模板变量与后面的参数一并传递给过滤器
    <li>{{ time.week|mod:3}}</li>

模板注释

1
2
3
4
5
6
7
# 单行注视
{# 注释内容 #}

# 多行注释
{% comment %}
注释内容
{% endcomment %}

模板继承

web端的网页信息,有很多内容有时是重叠的,这个时候我们就可以将重叠的内容部分单独设定为一个父级模板文件,其他的模板文件用于继承父级的模板文件,操作方式如下:

  1. 创建基模板文件【base.html】

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>
    {% block title %}
    当子模板中不同的内容需要重写的时候,则需要事先预留好位置,通过block的模板标签
    {% endblock title %}
    </title>
    </head>
    <body>
    {% block body%}
    block中的内容是可以不写的,但是也可以写
    {% endblock body%}
    </body>
    </html>
  2. 创建子模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    {# 首先需要引入基模板文件,它的路径相对于templates文件夹 #}
    {% extends "User/base.html" %}


    {# 重写指定block中的内容的时候,也需要通过block模板标签进行操作 #}
    {% block title %}
    {# 默认基模板中填充的内容是直接被覆盖的,若需要展示基模板中内容,则通过super方式引入#}
    {{ block.super }}

    中间写该block所填充的内容
    {% endblock title %}

模板转义

  • 产生

    凡是通过视图传递给模板的内容中的html标签都会被转义成转义字符,导致html标签被当作内容显示在了前台

  • 解决方案

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 通过{{模板变量:safe}}解决
    <div>
    {{html_data:safe}}
    </div>


    # 通过模板标签
    {% autoescape off %}
    # 设置为off,则中间传递的模板变量中所有的html标签都不会转义
    # 设置为on,则中间传递的模板变量中的html标签都会转义
    {% endautoescape %}
  • 备注

    模板文件中硬编码的html内容默认不会转义,如需转义则需要手动处理

    1
    2
    # 如模板文件中如下内容
    {{ data|default: "<h1>该标签就不会被转义</h1>"}}