Django - 模板

概述

  • 模板由两部分组成:
    • HTML 代码
    • 逻辑控制代码:
      • 变量
      • 标签
      • 过滤器
  • 作用:很便利的生成 HTML
  • 优点:模板的设计实现了业务逻辑与显示的分离,一个视图可以使用任意的模板,一个模板可以被多个视图使用
  • 模板的处理:
    • 加载:根据给定的标识找到对应的模板然后预处理,通常将它编译好放到到内存中
    • 渲染:使用 context 属性的数据插入模板形成新的字符串

定义模板

  • 使用前提

    • 在工程目录下创建名为 templates 的目录,在 settings.py 文件中配置 templates 目录的路径
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      TEMPLATES = [
      {
      'BACKEND': 'django.template.backends.django.DjangoTemplates',
      'DIRS': [BASE_DIR / 'templates'],
      'APP_DIRS': True,
      'OPTIONS': {
      'context_processors': [
      'django.template.context_processors.debug',
      'django.template.context_processors.request',
      'django.contrib.auth.context_processors.auth',
      'django.contrib.messages.context_processors.messages',
      ],
      },
      },
      ]
  • 变量

    • 语法:

      1
      {{ var }}
    • 要遵守标识符规则

    • 在模板中使用点语法,按照顺序查询:

      • 字典查询
      • 属性或者方法查询
      • 数字索引查询
    • 如果使用的变量不存在,则插入空字符串

    • 在模板中调用对象的方法:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      <body>
      <h1>{{ num }}</h1>
      <h1>{{ flag }}</h1>
      <h1>{{ string }}</h1>
      <h1>{{ stu.name }}</h1>
      <h1>*{{ hobby }}*</h1>
      <h1>{{ stu.run }}</h1>
      <ul>
      {% for item in stus %}
      <li>{{ item.name }}--{{ item.grade }}--{{ item.age }}</li>
      {% endfor %}
      </ul>
      </body>

      注意:调用函数不能传递参数

  • 标签

    • 简介

      • 基本语法
        1
        {% tag %}
      • 有些标签要求有开始和结束标签
        1
        {% tag %} ... tag contents ... {% endtag %}
      • 作用
        • 在输出中创建文本
        • 控制循环或逻辑
        • 加载外部信息到模板中供以后的变量使用
    • if

      • {% if %} 标签会判断给定的变量,当变量为 True 时(比如存在、非空、非布尔值 False),就会输出块内的内容
      • 格式
        1
        2
        3
        {% if 表达式 %}
        语句
        {% endif %}
        1
        2
        3
        4
        5
        {% if 表达式 %}
        语句1
        {% else %}
        语句2
        {% endif %}
        1
        2
        3
        4
        5
        6
        7
        8
        {% if 表达式1 %}
        语句1
        {% elif 表达式2 %}
        语句2
        ……
        {% else %}
        语句e
        {% endif %}
      • 示例
        1
        2
        3
        {% if num > 15 %}
        <h1>sunck is a good man</h1>
        {% endif %}
    • for

      • 循环浏览数组中的每个项目,使该项目在上下文变量中可用
      • 当传递到 for 标签中的数组不存在或为空时,可以使用 {% empty %} 标签来指定输出的内容
      • 格式
        1
        2
        3
        {% for 变量 in 集合 %}
        语句
        {% endfor %}
        1
        2
        3
        4
        5
        {% for 变量 in 集合 %}
        语句
        {% empty %}
        如果给出的集合为空或者集合不存在则执行这里
        {% endfor %}
      • 示例
        1
        2
        3
        4
        5
        6
        7
        <ul>
        {% for item in stus1 %}
        <li>{{ item.name }}--{{ item.grade }}--{{ item.age }}</li>
        {% empty %}
        <h1>没有学生</h1>
        {% endfor %}
        </ul>
    • comment

      • 多行注释,忽略 {% comment %} {% endcomment %} 之间的所有内容。可以在第一个标签中插入一个可选的注释。例如,这在注释代码时很有用,可以记录代码被禁用的原因。
      • 格式
        1
        2
        3
        {% comment "注释" %}
        多行注释
        {% endcomment %}
    • ifequal 和 ifnotequal

      • 3.1 版后已移除
      • 格式

        1
        2
        3
        {% ifequal 值1 值2 %}
        语句
        {% endifequal %}

        值 1 等于值 2 则执行语句

        1
        2
        3
        {% ifnotequal 值1 值2 %}
        语句
        {% endifnotequal %}

        值 1 不等于值 2 才执行语句

    • inluce

      • 加载一个模板,并在当前上下文中进行渲染。这是一种在模板中 “包含” 其他模板的方式
      • 模板名称可以是一个变量,也可以是一个硬编码(引号)字符串,可以是单引号或双引号
      • 格式
        1
        {% include "模板目录" %}
    • url

      • 反向解析,返回与给定视图和可选参数相匹配的绝对路径引用(不含域名的 URL)。路径中的任何特殊字符将使用 iri_to_uri() 进行编码
      • 格式
        1
        {% url "namespace:name" 参数1 …… %}
    • csrf_token

    • block

      • block:定义一个可以被子模板覆盖的块。更多信息请参见 模板继承
    • extends

      • 表示该模板扩展 (继承) 了一个父模板
      • 这个标签有两种使用方式
        • {% extends "base.html" %} (带引号)使用字面值 "base.html" 作为要扩展的父模板的名称
        • {% extends variable %} 使用 variable 的值。如果变量的值是一个字符串,Django 将使用这个字符串作为父模板的名称。如果变量的值是一个 Template 对象,Django 将使用该对象作为父模板
    • autoescape

      • 控制当前的自动转义行为。该标签以 onoff 作为参数,决定块内是否有自动转义行为。此区块以 endautoescape 结束标签关闭。
      • 当自动转义生效时,所有的变量内容在将结果放入输出之前(但在任何过滤器被应用之后)都会被应用 HTML 转义。这相当于对每个变量手动应用 escape 过滤器。
      • 唯一的例外是那些已经被标记为 “安全” 的变量,这些变量可以是被填充变量的代码标记的,也可以是被应用了 safeescape 过滤器的。
      • 格式
        1
        2
        3
        {% autoescape on %}
        {{ body }}
        {% endautoescape %}
    • debug

      • 输出整体的调试信息,包括当前上下文和导入的模块。
    • filter

      • 通过一个或多个过滤器过滤块的内容。可以用管道指定多个过滤器,过滤器可以有参数,就像变量语法一样。
      • 请注意,该块包括 filterendfilter 标签之间的 所有 文本。
    • firstof

      • 输出第一个不是 false 的参数变量(即存在、不为空、不是一个错误的布尔值,也不是一个零的数值)。如果所有传递的变量都是 false,则不输出任何内容。
      • 示例:
        1
        {% firstof var1 var2 var3 %}
      • 这相当于:
        1
        2
        3
        4
        5
        6
        7
        {% if var1 %}
        {{ var1 }}
        {% elif var2 %}
        {{ var2 }}
        {% elif var3 %}
        {{ var3 }}
        {% endif %}
    • ifchanged

      • 检查一个值是否在循环的最后一次迭代中发生了变化。
      • {% ifchanged %} 块标签用于循环中。
    • load

      • 加载一个自定义模板标签集。
    • lorem

      • 显示随机的 “经验之谈” 拉丁文文本。这对于在模板中提供样本数据很有用。
      • 用法
        1
        {% lorem [count] [method] [random] %}
    • now

      • 显示当前日期和/或时间,根据给定的字符串使用格式。这些字符串可以包含格式指定符,如 date 过滤器部分所述。
    • regroup

      • 通过一个共同的属性将一个相似的对象列表重新分组。
    • spaceless

      • 删除 HTML 标签之间的空白。这包括制表符和换行符。
      • 示例
        1
        2
        3
        4
        5
        {% spaceless %}
        <p>
        <a href="foo/">Foo</a>
        </p>
        {% endspaceless %}
      • 这个例子会返回这样的 HTML
        1
        <p><a href="foo/">Foo</a></p>
    • templatetag

      • 输出用于组成模板标签的语法字符之一。
    • verbatim

      • 停止模板引擎渲染此块标签的内容。
      • 常见的用法是允许 JavaScript 模板层与 Django 的语法发生碰撞。例如:
        1
        2
        3
        {% verbatim %}
        {{if dying}}Still alive.{{/if}}
        {% endverbatim %}
    • widthratio

      • 对于创建条形图等,该标签计算给定值与最大值的比率,然后将该比率应用于一个常数。
      • 示例
        1
        2
        <img src="bar.png" alt="Bar"
        height="10" width="{% widthratio this_value max_value max_width %}">
    • with

      • 将一个复杂的变量缓存在一个简单的名称下。当多次访问一个 “昂贵的” 方法(例如,访问数据库的方法)时,这很有用。
      • 示例
        1
        2
        3
        {% with total=business.employees.count %}
        {{ total }} employee{{ total|pluralize }}
        {% endwith %}
  • 过滤器

    • 简介

      • 语法
        1
        {{ 变量|过滤器 }}
      • 作用:在变量被显示前修改它的显示
    • lower

      • 将一个字符串转换为全小写。
        1
        {{ value|lower }}

        如果 valueTotally LOVING this Album!,则输出为 totally loving this album!

    • upper

      • 将一个字符串转换为全大写。
        1
        {{ value|upper }}

        如果 value"Joel is a slug",则输出将是 "JOEL IS A SLUG"

    • urlencode

      • 转义一个值用于 URL。

        1
        {{ value|urlencode }}

        如果 value"https://www.example.org/foo?a=b&c=d",则输出将是 "https%3A//www.example.org/foo%3Fa%3Db%26c%3Dd"

    • urlize

      • 将文本中的 URL 和电子邮件地址转换为可点击的链接。

        1
        {{ value|urlize }}

        如果 value"Check out www.djangoproject.com",则输出将是 "Check out <a href="http://www.djangoproject.com" rel="nofollow">www.djangoproject.com</a>"

    • urlizetrunc

      • urlize 一样,将 URL 和电子邮件地址转换为可点击的链接,但会截断长于给定字符限制的 URL。
      • 参数: 链接文本应截断的字符数,包括必要时添加的省略号。
        1
        {{ value|urlizetrunc:15 }}

        如果 value"Check out www.djangoproject.com",则将输出 'Check out <a href="http://www.djangoproject.com" rel="nofollow">www.djangoproj…</a>'

    • wordcount

      • 返回单词的数量。

        1
        {{ value|wordcount }}

        如果 value"Joel is a slug",则输出将是 4

    • wordwrap

      • 以指定的行长度包装文字。
      • 参数: 包裹文本的字符数
        1
        {{ value|wordwrap:5 }}
      • 如果 valueJoel is a slug,则输出将是:
        1
        2
        3
        Joel
        is a
        slug
    • yesno

      • TrueFalse 和(可选的) None 值映射到字符串 “yes”、“no”、“maybe” 或以逗号分隔的列表形式传递的自定义映射,并根据值返回其中一个字符串。
        1
        {{ value|yesno:"yeah,no,maybe" }}
        参数 输出
        True yes
        True "yeah,no,maybe" yeah
        False "yeah,no,maybe" no
        None "yeah,no,maybe" maybe
        None "yeah,no" no (如果没有给出 None 的映射,则将 None 转换为 False
    • title

      • 将单词的首字母大写,其它字母小写。
        1
        {{ value|title }}

        如果 value"my FIRST post",则输出将是 "My First Post"

    • truncatechars

      • 如果一个字符串的长度超过指定的字符数,则截断它。截断后的字符串将以一个可翻译的省略号(“...”)结束。
      • 参数: 要截断的字符数
        1
        {{ value|truncatechars:7 }}

        如果 value"Joel is a slug",则输出将是 "Joel i…"

    • truncatechars_html

      • 类似于 truncatechars,只是它能识别 HTML 标签。任何在字符串中打开但在截断点之前没有关闭的标签都会在截断后立即关闭。
        1
        {{ value|truncatechars_html:7 }}

        如果 value"<p>Joel is a slug</p>",则输出将是 "<p>Joel i…</p>"
        HTML 内容中的新行将被保留。

    • truncatewords

      • 在一定字数后截断字符串。
      • 参数: 要在之后截断的字数
        1
        {{ value|truncatewords:2 }}

        如果 value"Joel is a slug",则输出将是 "Joel is …"

      • 字符串内的新行将被删除。
    • truncatewords_html

      • 类似于 truncatewords,只是它能识别 HTML 标签。任何在字符串中打开的标签,如果在截断点之前没有关闭,则会在截断后立即关闭。
      • 这比 truncatewords 效率低,所以只能在传递 HTML 文本时使用。
        1
        {{ value|truncatewords_html:2 }}

        如果 value"<p>Joel is a slug</p>",则输出将是 "<p>Joel is …</p>"

      • HTML 内容中的新行将被保留。
    • unordered_list

      • 递归地接受一个自嵌套列表,并返回一个 HTML 无序列表 —— 没有 打开和关闭 <ul> 标签。
      • 假定列表的格式正确。例如,如果 var 包含 ['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']],那么 {{ var|unordered_list }} 将返回:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        <li>States
        <ul>
        <li>Kansas
        <ul>
        <li>Lawrence</li>
        <li>Topeka</li>
        </ul>
        </li>
        <li>Illinois</li>
        </ul>
        </li>
    • capfirst

      • 将值的第一个字符大写。如果第一个字符不是字母,这个过滤器就没有效果。

        1
        {{ value|capfirst }}

        如果 value"django",则输出为 "Django"

    • center

      • 在给定宽度的字段中使数值居中。

        1
        "{{ value|center:"15" }}"

        如果 value"Django",输出将是 " Django "

    • cut

      • 从给定的字符串中删除参数的所有值。

        1
        {{ value|cut:" " }}

        如果 value"String with spaces",输出将是 "Stringwithspaces"

    • join

      • 将列表拼接成字符串,过滤器可以传递参数。

        1
        {{ value|join:" // " }}

        如果 value 是列表 ['a', 'b', 'c'],输出将是字符串 "a // b // c"

    • json_script

      • 安全地将 Python 对象输出为 JSON,用 <script> 标签包装,准备好与 JavaScript 一起使用。
      • 参数: HTML <script> 标签的 “id”。
        1
        {{ value|json_script:"hello-data" }}
      • 如果 value 是字典 {'hello':'world'},则输出为
        1
        <script id="hello-data" type="application/json">{"hello": "world"}</script>
    • default

      • 如果值为 False,则使用给定的默认值。否则,使用该值。
        1
        {{ value|default:"nothing" }}

        如果 value"" (空字符串),输出将是 nothing

    • default_if_none

      • 如果(也只有当)值是 None,使用给定的默认值。否则,使用该值。
      • 请注意,如果给定一个空字符串,将 不会 使用默认值。如果你想使用空字符串,请使用 default 过滤器。
        1
        {{ value|default_if_none:"nothing" }}

        如果 valueNone,则输出为 nothing

    • dictsort

      • 获取一个字典列表,并按照参数中给出的键排序返回该列表。

        1
        {{ value|dictsort:"name" }}
      • 如果 value

        1
        2
        3
        4
        5
        [
        {'name': 'zed', 'age': 19},
        {'name': 'amy', 'age': 22},
        {'name': 'joe', 'age': 31},
        ]
      • 那么输出将是

        1
        2
        3
        4
        5
        [
        {'name': 'amy', 'age': 22},
        {'name': 'joe', 'age': 31},
        {'name': 'zed', 'age': 19},
        ]
    • divisibleby

      • 如果数值被参数整除,则返回 True

        1
        {{ value|divisibleby:"3" }}

        如果 value21,则输出为 True

    • date

      • 根据给定的格式设置日期。

      • 使用与 PHP 的 date () 函数类似的格式,但有一些区别。

        1
        {{ value|date:"Y-m-d" }}
    • time

      • 根据给定的格式对时间进行格式化。
      • 给定的格式可以是预定义的 TIME_FORMAT,也可以是自定义的格式,和 date 过滤器一样。请注意,预定义的格式是依赖于 locale 的。
        1
        {{ value|time:"H:i" }}

        如果 value 相当于 datetime.datetime.now(),输出将是字符串 "01:23"

    • timesince

      • 将日期格式化为自该日期起的时间(如 “4 days, 6 hours”)。
      • 取一个可选参数,该参数是一个变量,包含作为比较点的日期(如果没有该参数,比较点是 现在 )。例如,如果 blog_date 是代表 2006 年 6 月 1 日午夜的日期实例,comment_date 是 2006 年 6 月 1 日 08:00 的日期实例,那么下面将返回 “8 hours”:
        1
        {{ blog_date|timesince:comment_date }}
      • 比较本地偏移和感知偏移的日期会返回一个空字符串。
      • 分钟是使用的最小单位,凡是相对于比较点来说是未来的日期,都会返回 “0 minutes”。
    • timeuntil

      • timesince 类似,不同的是,它测量的是从现在到给定日期或日期时间的时间。例如,如果今天是 2006 年 6 月 1 日,而 conference_date 是一个持有 2006 年 6 月 29 日的日期实例,那么 {conference_date|timeuntil }} 将返回 “4 weeks”。
      • 取一个可选参数,该参数是一个包含日期的变量,用来作为比较点(而不是 现在)。如果 from_date 包含 2006 年 6 月 22 日,那么下面将返回 “1 week”:
        1
        {{ conference_date|timeuntil:from_date }}
      • 比较本地偏移和感知偏移的日期会返回一个空字符串。
      • 分钟是使用的最小单位,相对于比较点而言,任何处于过去的日期都将返回 “0 minutes”。
    • escape

      • 转义字符串的 HTML。具体来说,它可以进行这些替换。
        • < 被替换为 <
        • > 被替换为 >
        • ' (单引号)被替换为 '
        • " (双引号)被替换为 "
        • & 被替换为 &
      • escape 应用到一个通常会对结果进行自动转义的变量上,结果只会进行一轮转义。所以即使在自动转义环境中使用这个函数也是安全的。如果你想进行多次转义,请使用 force_escape 过滤器。
    • escapejs

      • 在 JavaScript 字符串中使用的转义字符。这并不能使字符串安全地用于 HTML 或 JavaScript 模板字元,但可以保护你在使用模板生成 JavaScript/JSON 时避免语法错误。

        1
        {{ value|escapejs }}

        如果 value"testing\r\njavascript 'string\" <b> escaping </b>",则输出为 "testing\\u000D\\u000Ajavascript\\u0027string\\u0022\\u003Cb\\u003Eescaping\\u003C/b\\u003E"

    • force_escape

      • 对字符串进行 HTML 转义处理(详情请参见 escape 过滤器)。这个过滤器会 立即 应用,并返回一个新的转义字符串。在极少数情况下,当你需要多次转义或想对转义结果应用其他过滤器时,这很有用。通常情况下,你要使用 escape 过滤器。

        1
        2
        3
        {% autoescape off %}
        {{ body|linebreaks|force_escape }}
        {% endautoescape %}

        例如,如果你想捕捉由 linebreaks 过滤器创建的 <p> HTML 元素

    • get_digit

      • 给定一个整数,返回要求的数字,其中 1 是最右边的数字,2 是最右边的数字,等等。对于无效的输入(如果输入或参数不是整数,或者参数小于 1),返回原始值。否则,输出总是一个整数。

        1
        {{ value|get_digit:"2" }}

        如果 value123456789,则输出为 8

    • iriencode

      • 将 IRI(国际化资源标识符)转换为适合包含在 URL 中的字符串。如果你想在 URL 中使用包含非 ASCII 字符的字符串,这一点是必要的。
      • 在已经通过 urlencode 过滤器的字符串上使用这个过滤器是安全的。
        1
        {{ value|iriencode }}

        如果 value"?test=1&me=2",则输出为 "?test=1&me=2"

    • first

      • 返回列表中的第一个项目。

        1
        {{ value|first }}

        如果 value 是列表 ['a', 'b', 'c'],则输出为 'a'

    • last

      • 返回列表中的最后一项。

        1
        {{ value|last }}

        如果 value 是列表 ['a', 'b', 'c', 'd'],输出将是字符串 "d"

    • random

      • 从给定列表中随机返回一个项目。

        1
        {{ value|random }}

        如果 value 是列表 ['a', 'b', 'c', 'd'],输出可能是 "b"

    • length

      • 返回值的长度。这对字符串和列表都有效。

        1
        {{ value|length }}

        如果 value['a', 'b', 'c', 'd']"abcd",输出将是 4

      • 过滤器对未定义的变量返回 0

    • length_is

      • 如果值的长度是参数,则返回 True,否则返回 False

        1
        {{ value|length_is:"4" }}

        如果 value['a', 'b', 'c', 'd']"abcd",输出将是 True

    • linebreaks

      • 用适当的 HTML 替换纯文本中的换行符;一个新行成为 HTML 换行符(<br>),一个新行后的空行成为段落换行符(</p>)。

        1
        {{ value|linebreaks }}

        如果 valueJoel\nis a slug,则输出为 <p>Joel<br>is a slug</p>

    • linebreaksbr

      • 将一段纯文本中的所有换行符转换为 HTML 换行符(<br>)。

        1
        {{ value|linebreaksbr }}

        如果 valueJoel/nis a slug,则输出为 Joel<br>is a slug

    • linenumbers

      • 显示带有行号的文本。

        1
        {{ value|linenumbers }}
      • 如果 value

        1
        2
        3
        one
        two
        three
      • 输出将是

        1
        2
        3
        1. one
        2. two
        3. three
    • ljust

      • 左对齐给定宽度的字段中的值。
      • 参数: 字段大小
        1
        "{{ value|ljust:"10" }}"

        如果 valueDjango,则输出为 "Django "

    • rjust

      • 右对齐给定宽度的字段中的值。
      • 参数: 字段大小
        1
        "{{ value|rjust:"10" }}"

        如果 valueDjango,输出将是 " Django"

    • slice

      • 返回列表的一个片段。
      • 使用与 Python 列表切片相同的语法。有关介绍,请参阅:slicinglists
        1
        {{ some_list|slice:":2" }}

        如果 some_list['a', 'b', 'c'],输出将是 ['a', 'b']

    • slugify

      • 转换为 ASCII 码。将空格转换为连字符。移除非字母数字、下划线或连字符的字符。转换为小写字母。还可以去除前导和尾部的空白。

        1
        {{ value|slugify }}

        如果 value"Joel is a slug",那么输出将是 "joel-is-a-slug"

    • make_list

      • 返回变成列表的值。对于字符串,它是一个字符列表。对于整数来说,在创建列表之前,参数会被转换为一个字符串。

        1
        {{ value|make_list }}

        如果 value 是字符串 "Joel",输出将是列表 ['J', 'o', 'e', 'l']。如果 value123,输出将是列表 ['1','2','3']

    • phone2numeric

      • 将一个电话号码(可能包含字母)转换为其数字等价物。
      • 输入的不一定是有效的电话号码。这将很乐意转换任何字符串。
        1
        {{ value|phone2numeric }}

        如果 value800-COLLECT,则输出为 800-2655328

    • pluralize

      • 如果值不是 1'1' 或长度为 1 的对象,则返回复数后缀。 默认情况下,后缀为 's'

        1
        You have {{ num_messages }} message{{ num_messages|pluralize }}.

        如果 num_messages1,输出将是 You have 1 message. 如果 num_messages2,输出将是 You have 2 messages.

    • floatformat

      • 当不使用参数时,将浮点数四舍五入到小数点后一位 —— 但只在有小数部分要显示的情况下。

        value 模板 输出
        34.23234 {{ value|floatformat }} 34.2
        34.00000 {{ value|floatformat }} 34
        34.26000 {{ value|floatformat }} 34.3
      • 如果与数字整数参数一起使用,floatform 将一个数字四舍五入到小数点后几位。

        value 模板 输出
        34.23234 {{ value|floatformat:3 }} 34.232
        34.00000 {{ value|floatformat:3 }} 34.000
        34.26000 {{ value|floatformat:3 }} 34.260
    • stringformat

      • 根据参数 —— 字符串格式化指定器,对变量进行格式化。这个指定符使用 printf-style String Formatting 语法,例外的是前面的 “%” 被删除。

        1
        {{ value|stringformat:"E" }}

        如果 value10,则输出为 1.000000E+01

    • filesizeformat

      • 以 “人类可读” 的文件大小为格式(如 '13 KB''4.1 MB''102 bytes' 等)。

        1
        {{ value|filesizeformat }}

        如果 value 是 123456789,则输出为 117.7 MB

    • striptags

      • 尽一切努力剥离所有 [X] HTML 标签。

        1
        {{ value|striptags }}

        如果 value"<b>Joel</b> <button>is</button> a <span>slug</span>", 那么输出就会是 "Joel is a slug"

    • safe

      • 标记一个字符串在输出前不需要进一步的 HTML 转义。当自动转义关闭时,该过滤器没有效果。
    • safeseq

      • safe 过滤器应用于序列的每个元素。与其他对序列进行操作的过滤器,如 join 一起使用。

        1
        {{ some_list|safeseq|join:", " }}
      • 在这种情况下,你不能直接使用 safe 过滤器,因为它会首先将变量转换为字符串,而不是处理序列中的单个元素。

    • add

      • 加法或减法,这个过滤器将首先尝试将两个值强制转为整数。如果失败了,它将尝试将两个值加在一起。这对某些数据类型(字符串、列表等)有效,而对其他类型则失败。如果失败,结果将是一个空字符串。
        1
        {{ value|add:"2" }}

        如果 value4,那么输出将是 6

        1
        {{ value|add:"-2" }}

        如果 value4,那么输出将是 2

        1
        {{ first|add:second }}

        如果 first[1, 2, 3] 并且 second[4, 5, 6],则输出为 [1, 2, 3, 4, 5, 6]

    • 乘除

      • 无法用过滤器实现
      • 用标签实现
        1
        2
        3
        4
        {# widthratio arg1 arg2 arg3   #}
        {# arg1/arg2*arg3 #}
        <h1>{% widthratio num 1 2 %}</h1>
        <h1>{% widthratio num 2 1 %}</h1>
    • 自定义过滤器

      • 过滤器就是 python 中的函数,可以注册函数后在模板中当过滤器使用
      • 在应用目录下创建名为 templatetags 的包
      • templatetags 目录下创建名为 filters.py 的文件
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        # -*- coding:utf-8 -*-

        #导入Library库
        from django.template import Library

        #创建一个Library对象
        register = Library()

        #使用装饰器进行注册过滤器
        @register.filter
        def mod(value):
        return value % 2 == 0
        1
        2
        3
        @register.filter
        def mod(value, num):
        return value % num == 0
      • 在模板中引入(如果无效重启应用即可)
        1
        2
        3
        4
        {% load filters %}
        {% if 9|mod %}
        <h1>sunck is a nice man</h1>
        {% endif %}

反向解析

  • 主路由:

    1
    url(r'^', include('myApp.urls', namespace="sunck")),
  • 子路由:

    1
    url(r'^t3test1/(\d+)/$', views.t3test, name="t3test"),
  • 链接代码:

    1
    <a href="{% url 'sunck:t3test' 5 %}">点我跳转</a>

HTML 转义

  • 默认开启转义:不解析,解析成普通字符串

  • 关闭转义:开启解析,有些被解析成 HTML 标签

    1
    2
    3
    4
    5
    def t4(request):
    test1 = "<script type='text/javascript'>alert('autoescape off:关闭转义')</script>"
    test2 = "<h1>escape:开启转义</h1>"
    test3 = '<h1>safe:关闭转义</h1>'
    return render(request, 'myApp/t4.html', {'string1': test1, 'string2': test2, 'string3': test3})
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>转义</title>
    </head>
    <body>
    {#autoescape off:关闭转义#}
    {#autoescape on:开启转义#}
    {# {% autoescape off %}#}
    {# {{ string1 }}#}
    {# {% endautoescape %}#}

    {#escape:开启转义#}
    {# {% autoescape off %}#}
    {# {{ string1 }}#}
    {# {{ string2|escape }}#}
    {# {% endautoescape %}#}

    {#safe:关闭转义#}
    {{ string3|safe }}
    </body>
    </html>

跨站请求伪造

  • 某些恶意的网站上包含链接、表单按钮或者 JavaScript,他们会利用登陆过的用户认证信息试图在你的网站上完成某些操作,这就是跨站攻击。
  • 防止 csrf:
    • settings.py 中启用'django.middleware.csrf.CsrfViewMiddleware', 中间件,此项在创建工程时就默认启用
  • 验证表单:
    1
    {% csrf_token %}

    1. 在客户端存入一个名为 csrftoken 的 cookie
    2. 给表单增加一个隐藏域,value 值为名为 scrftoken 的 cookie 的键进行的加密

继承

  • 作用:模板的继承可以减少页面的重复定义,实现页面的重用

  • 实现:

    • block 标签:在父模板中预留区域,在子模板中填充
    • extends 标签:继承,写在模板的第一行
  • 示例:

    • 父模板:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <title>{% block title %}{% endblock title %}</title>

      {% block link %}{% endblock link %}

      {% block script %}{% endblock script %}
      </head>
      <body>
      <header>头部</header>
      <div>
      {% block main %}
      {% endblock main %}
      </div>
      <footer>尾部</footer>
      </body>
      </html>
    • 子模板:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      {% extends 'myApp/base.html' %}

      {% block title %}主页{% endblock title %}

      {% block link %}{% endblock link %}

      {% block script %}{% endblock script %}

      {% block main %}
      <h1>home</h1>
      {% endblock main %}
  • 包含项目中的 css、js、图片、json 等文件
  • 在工程目录创建名为 static 的目录作为静态文件的存放位置
  • 配置 settings.py 文件
    1
    2
    3
    4
    STATIC_URL = 'static/'
    STATICFILES_DIRS = [
    BASE_DIR / 'static',
    ]
  • 使用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {% load static from staticfiles %}
    {#{% load static %}#}
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>首页</title>
    {# <link rel="stylesheet" type="text/css" href="/static/css/index.css" />#}
    <link rel="stylesheet" type="text/css" href="{% static 'css/index.css' %}"/>
    </head>
    <body>
    <h1>sunck is a good man</h1>
    </body>
    </html>
  • 部署
    django.contrib.staticfiles 提供了一个便利的管理命令,用于将静态文件收集至独立目录,方便你为它们提供服务。
    1. STATIC_ROOT 配置成你喜欢的目录,在这个目录提供服务,例如:
      1
      STATIC_ROOT = "/var/www/example.com/static/"
    2. 运行 collectstatic 管理命令:
      1
      python manage.py collectstatic

      这将会把静态目录下的所有文件拷贝至 STATIC_ROOT 目录。

    3. 选一个 Web 服务器为这些文件提供服务。 文档 How to deploy static files 介绍了静态文件的常见部署策略。