DTL语法

作者: 蝉时雨丶 | 来源:发表于2020-06-10 17:58 被阅读0次

模板

A template is a text file. It can generate any text-based format (HTML, XML, CSV, etc.).

模板中包含的 变量 被替换为变量的值, 标签 被替换为相应的模板控制逻辑.

Below is a minimal template that illustrates a few basics. Each element will be explained later in this document.

{% extends "base_generic.html" %}

{% block title %}{{ section.title }}{% endblock %}

{% block content %}
<h1>{{ section.title }}</h1>

{% for story in story_list %}
<h2>
  <a href="{{ story.get_absolute_url }}">
    {{ story.headline|upper }}
  </a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}

变量

Variables look like this: {{ variable }}. When the template engine encounters a variable, it evaluates that variable and replaces it with the result. Variable names consist of any combination of alphanumeric characters and the underscore ("_") but may not start with an underscore. The dot (".") also appears in variable sections, although that has a special meaning, as indicated below. Importantly, you cannot have spaces or punctuation characters in variable names.

使用点 (.) 来访问变量的属性.

在上面的例子中, {{ section.title }} 将被替换为这个对象的title属性值.

If you use a variable that doesn't exist, the template system will insert the value of the string_if_invalid option, which is set to '' (the empty string) by default.

Note that "bar" in a template expression like {{ foo.bar }} will be interpreted as a literal string and not using the value of the variable "bar", if one exists in the template context.

Variable attributes that begin with an underscore may not be accessed as they're generally considered private.

过滤器

Filter arguments that contain spaces must be quoted; for example, to join a list with commas and spaces you'd use {{ list|join:", " }}.

Django provides about sixty built-in template filters. You can read all about them in the built-in filter reference. To give you a taste of what's available, here are some of the more commonly used template filters:

default

If a variable is false or empty, use given default. Otherwise, use the value of the variable. For example:

{{ value|default:"nothing" }}

如果 value 没有提供或者为空,那么他将显示为 "nothing" .

length

Returns the length of the value. This works for both strings and lists. For example:

{{ value|length }}

如果 value 为 ['a', 'b', 'c', 'd'], 那么他将被显示为 4.

filesizeformat

Formats the value like a "human-readable" file size (i.e. '13 KB', '4.1 MB', '102 bytes', etc.). For example:

{{ value|filesizeformat }}

If value is 123456789, the output would be 117.7 MB.

这些只是几个例子,请参阅 内置过滤器参考 的完整列表.

您还可以创建自己的自定义模板过滤器,请参见 自定义模板(template)的标签(tags)和过滤器(filters).

标签(Tags)

标签看起来像这样: {% tag %}. 标签要比变量更复杂: 有些标签会创建一段文本, 有些标签会控制输出流的方式比如循环或逻辑条件, 还有些标签会添加一些扩展内容到模板中, 比如另外的标签和过滤器.

有些标签在使用时需要有开始和结束标签 (像这样 {% tag %} ... 内容 ... {% endtag %}).

Django内置了大约二十几个标签. 你可以在 内置标签参考 阅读有关内置标签的内容. 为了让你尝试有什么可用的, 这里有一些常用标签的例子:

for

循环数组中的每个元素. 比如, 显示列表 athlete_list 中每个元素的 name 属性:

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}
</ul>

if, elif, and else

判断一个变量的布尔值, 如果它为 "true" 则显示 if 块儿内的内容, 否则显示 else 块儿内的文字:

{% if athlete_list %}
    Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
    Athletes should be out of the locker room soon!
{% else %}
    No athletes.
{% endif %}

In the above, if athlete_list is not empty, the number of athletes will be displayed by the {{ athlete_list|length }} variable. Otherwise, if athlete_in_locker_room_list is not empty, the message "Athletes should be out..." will be displayed. If both lists are empty, "No athletes." will be displayed.

也可以在 if 标签里使用过滤器和各种操作符:

{% if athlete_list|length > 1 %}
   Team: {% for athlete in athlete_list %} ... {% endfor %}
{% else %}
   Athlete: {{ athlete_list.0.name }}
{% endif %}

While the above example works, be aware that most template filters return strings, so mathematical comparisons using filters will generally not work as you expect. length is an exception.

block and extends

请看 模板继承 (在下面), 一个强大的方法, 在模板上切割下来的"样板".

以上的例子只是整个标签列表的一小部分; 请参看 内置标签参考 完整阅览.

您还可以创建自己的自定义模板标签, 请参看 自定义模板(template)的标签(tags)和过滤器(filters).

注释(Comments)

要注释掉行的一部分,在模板中使用注释语法: {# #}.

例如,该模板将呈现为 'hello':

{# greeting #}hello

注释可以包含任何模板代码, 使其生效或无效. 例如:

{# {% if foo %}bar{% else %} #}

这个语法只能用于单行注释 (不允许在 {##} 之间换行). 如果您需要注释掉多行部分的模板, 参见 comment 标签.

模板继承

Django模板中最强大和最复杂的部分就是模板继承. 模板继承允许你建立一个基本的"骨架"模板, 它包含了你网站所有常见的元素,并定义了可以被子模板覆盖的 块(blocks) .

Let's look at template inheritance by starting with an example:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css">
    <title>{% block title %}My amazing site{% endblock %}</title>
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        {% endblock %}
    </div>

    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

This template, which we'll call base.html, defines an HTML skeleton document that you might use for a two-column page. It's the job of "child" templates to fill the empty blocks with content.

在这个例子中, block 标签定义了三个可以被子模板填充的块. block 标签告诉了模板系统哪些地方可能被子模板覆盖.

一个子模板可能看起来像这样:

{% extends "base.html" %}

{% block title %}My amazing blog{% endblock %}

{% block content %}
{% for entry in blog_entries %}
    <h2>{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}

extends 标签是这里的关键. 它告诉模板系统这个模板继承了另外的模板. 当模板系统对此模板进行运算, 首先会寻找他的父模板 -- 在这里是"base.html".

在这一点上, 模板引擎会在 base.html 中发现三个 block 标签, 并且使用子模板的内容替换掉这些块. 根据变量 blog_entries 的值, 输出可能看起来像这样:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css">
    <title>My amazing blog</title>
</head>

<body>
    <div id="sidebar">
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
    </div>

    <div id="content">
        <h2>Entry one</h2>
        <p>This is my first entry.</p>

        <h2>Entry two</h2>
        <p>This is my second entry.</p>
    </div>
</body>
</html>

需要注意的是, 因为子模板没有定义 sidebar 块, 那么父模板的内容就会被使用. 通常来说, 父模板 {% block %} 中的内容会被作为备用的内容.

在你需要时, 可以有多个层次的继承关系. 使用模板继承的一个常用方案是像以下的三层继承.

  • 创建一个 base.html 模板把控你网站的整体风格.
  • 为网站的每个子分类创建一个 base_SECTIONNAME.html 模板. 比如, base_news.html, base_sports.html. 这些模板都继承 base.html 模板. 这些模板中包含特定的设计/风格.
  • 为每一种类型的页面创建一个模板, 比如 news article 或 blog 内容. 这些模板扩展上一级模板的相应分类.

This approach maximizes code reuse and helps to add items to shared content areas, such as section-wide navigation.

这里有一些关于模板继承的提示

  • 如果你在模板中使用 {% extends %}, 他必须位于模板的最开始. 如果在其他的部分声明, 则不生效.

  • 在你的基础模板中使用更多的 {% block %} 是一个好的方法. 请记住, 子模板不需要定义所有父模板中的块, 所以你可以在若干的块中填充默认值, 然后定义之后需要的块. 有更多的可用块总是更好的.

  • 如果你发现自己在许多模板中有重复内容的了, 这可能意味着你要移动这些内容到父模板的 {% block %} 中

  • 如果你需要得到父模板块中的内容, 可以用 {{ block.super }} 变量. 这在你想使用父模板块中的内容又想在其中追加内容时是非常有用的. 使用 {{ block.super }} 插入的数据不会被自动转义 (参见 下一节), 因为它已经被转义了. 如果需要转义, 可以在父模板中转义.

  • Variables created outside of a {% block %} using the template tag as syntax can't be used inside the block. For example, this template doesn't render anything:

{% trans "Title" as title %}
{% block content %}{{ title }}{% endblock %}
  • 更好的可读性, 你可以给 {% endblock %} 标签定义一个 名字. 比如:
{% block content %}
...
{% endblock content %}

在一个较长的模板中, 这个方法可以让你知道是哪一个 {% block %} 标签定义结束了.

最后请注意, 你不能在同一模板中定义多个具有相同名称的块标签. 存在这个限制是因为 block 标签是"双向"定义的. 也就是说, 它不仅指定了子模板要填充哪个"洞", 也说明了子模板要引用那些父模板的内容. 所以在有多个同名 block 标签时, 父模板就不知道到底要引用哪个块的内容了.

自动HTML转义

在Django中, 默认每个模板会自动转义输出的每一个变量标签. 具体来说, 这五个字符会被转义:

  • < 被替换为 <
  • > 被替换为 >
  • ' (single quote) is converted to '
  • " (双引号) 被替换为 "
  • & 被替换为 &

如何关闭它

对于单个变量

要为一个单独的变量禁用自动转义, 使用 safe 过滤器:

This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}

safe 可以被认为是 safe from further escaping 或 can be safely interpreted as HTML 的简写. 在这个例子中, 如果 data 是 '<b>', 那么输出将会是:

This will be escaped: &lt;b&gt;
This will not be escaped: <b>

对于模板文本块

To control auto-escaping for a template, wrap the template (or a particular section of the template) in the autoescape tag, like so:

{% autoescape off %}
    Hello {{ name }}
{% endautoescape %}

autoescape 标签接受 onoff 作为参数. 有时, 你希望自动转义在某个区域被禁用. 如这个模板的例子:

Auto-escaping is on by default. Hello {{ name }}

{% autoescape off %}
    This will not be auto-escaped: {{ data }}.

    Nor this: {{ other_data }}
    {% autoescape on %}
        Auto-escaping applies again: {{ name }}
    {% endautoescape %}
{% endautoescape %}

The auto-escaping tag passes its effect onto templates that extend the current one as well as templates included via the include tag, just like all block tags. For example:

{% autoescape off %}
<h1>{% block title %}{% endblock %}</h1>
{% block content %}
{% endblock %}
{% endautoescape %}
{% extends "base.html" %}
{% block title %}This &amp; that{% endblock %}
{% block content %}{{ greeting }}{% endblock %}

由于自动转义在base模板中被关闭了, 所以在子模板中他也是被关闭了的, 导致了在呈现HTML时, greeting 变量被输出为 <b>Hello!</b>:

<h1>This &amp; that</h1>
<b>Hello!</b>

字符串和自动转义

正如我们前面提到的, 过滤器参数可以是字符串:

{{ data|default:"This is a string literal." }}

这些作为过滤器参数的字符串 都不经过 自动转义, 他们是被认为经过了 safe 过滤器的. 这么做的原因是, 模板的开发者是在控制字符的输出, 所以他们能确保正确的使用转义后的HTML字面值.

这意味着你应当这么写

{{ data|default:"3 &lt; 2" }}

...rather than:

{{ data|default:"3 < 2" }}  {# Bad! Don't do this. #}

这不会影响来自变量本身的数据. 如果必要, 变量本身仍会被自动转义, 因为他们无法控制的模板作者.

访问方法调用

大多附加到对象上的方法都可以在模板中被调用.这意味着模板可以从视图中传递过来变量中获得对象属性之外的值.例如, Django ORM 提供了 "entry_set" 语法寻找一个外键所关联的对象的集合. 因此, 架设一个叫 "comment" 的模型有外键指向了模型 "task",你可以通过给定一个实际的 task , 像这样循环输出它所有的 comment:

{% for comment in task.comment_set.all %}
    {{ comment }}
{% endfor %}

同样, QuerySets 提供了一个 count() 方法来统计它所包含的对象数目. 因此, 您可以得到当前 task 相关的所有 comment 的数目:

{{ task.comment_set.all.count }}

And of course you can easily access methods you've explicitly defined on your own models:

class Task(models.Model):
    def foo(self):
        return "bar"
{{ task.foo }}

由于Django有意限制了模板中语言逻辑的处理, 所以不能在模板内调用方法时传递参数. 数据应当在视图中计算, 然后再传递给模板.

自定义标签和过滤器库

Certain applications provide custom tag and filter libraries. To access them in a template, ensure the application is in INSTALLED_APPS (we'd add 'django.contrib.humanize' for this example), and then use the load tag in a template:

{% load humanize %}

{{ 45000|intcomma }}

In the above, the load tag loads the humanize tag library, which then makes the intcomma filter available for use. If you've enabled django.contrib.admindocs, you can consult the documentation area in your admin to find the list of custom libraries in your installation.

The load tag can take multiple library names, separated by spaces. Example:

{% load humanize i18n %}

请参考 自定义模板(template)的标签(tags)和过滤器(filters) 以获得更多的有关自定义标签的内容.

自定义库和模板继承

当你加载一个自定义标签和过滤器库, 这些被加载的标签/过滤器只能在当前模板中使用 -- 其他与此模板有继承关系的(父/子)模板均不能使用这些标签/过滤器.

For example, if a template foo.html has {% load humanize %}, a child template (e.g., one that has {% extends "foo.html" %}) will not have access to the humanize template tags and filters. The child template is responsible for its own {% load humanize %}.

这是因为这能使模板更健全且更好维护.

相关文章

  • DTL语法

    模板 A template is a text file. It can generate any text-ba...

  • django DTL模板语法

    1.后端传递数据到前端 通过字典的方式返回给前端页面 2.前端显示信息 直接显示信息 显示对象的属性 更改显示对象...

  • 3.2 django模板语法

    DTL模板语法 模板变量: 模板中可以包含变量,Django在渲染模板的时候,可以传递变量对应的值过去进行替换。变...

  • django的模板语法1

    DTL模板语法 变量: 模板中可以包含变量,Django在渲染模板的时候,可以传递变量对应的值过去进行替换。变量的...

  • 最浅显易懂的Django系列教程(8)-模板变量

    DTL模板语法 变量: 模板中可以包含变量,Django在渲染模板的时候,可以传递变量对应的值过去进行替换。变量的...

  • Django学习-第三讲(下) Django 模板变量和常用标签

    1.DTL模板变量使用语法 模板中可以包含变量,Django在渲染模板的时候,可以传递变量对应的值过去进行替换。变...

  • 2018-08-08 模板

    DTL文件 Django文件中的模板系统主要是DTL模板语言,比普通HTML功能更为强大。 模板查找路径配置 模板...

  • django的模板语法

    目前市面上有非常多的模板系统,其中最知名最好用的就是DTL和Jinja2。DTL是Django Template ...

  • 模板语言: DTL

    1变量2 标签 { % 代码块 % }3 过滤器4 注释{# 代码或 html #} 1变量 语法: ...

  • Django模版语言

    模版语言:指导模版加载数据方式的工具。 DTL:Django Template Language

网友评论

      本文标题:DTL语法

      本文链接:https://www.haomeiwen.com/subject/wryptktx.html