[Django学习]五、Django官方文档--模板语言 解读

如果您有编程方面的背景,或者您已经习惯了将编程代码直接混合到HTML中的语言,那么您应该记住Django模板系统不仅仅是嵌入到HTML中的Python。这是通过设计:模板系统是用来表示,而不是程序逻辑。

Django模板系统提供的标记功能类似于一些编程构造if标记用于布尔测试,for用于循环等的标记-但是这些标记不仅仅是作为对应的Python代码执行的,模板系统也不会执行任意Python表达式。默认情况下,只支持下面列出的标记、筛选器和语法(尽管您可以添加你自己的扩展到模板语言)。

Django模板语言官方文档地址:https://docs.djangoproject.com/en/2.2/ref/templates/language/#the-django-template-language

一、模板

模板只是一个文本文件。它可以生成任何基于文本的格式(HTML、XML、CSV等).

模板包含变量,当计算模板时,这些值将被替换为值,以及标签,它控制模板的逻辑。

下面是一个说明一些基本知识的最小模板。每个元素将在本文档后面解释。

{% 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 %}

为什么要使用基于文本的模板而不是基于XML的模板(比如Zope的TAL)?我们希望Django的模板语言不仅仅适用于XML/HTML模板。在WorldOnline,我们将其用于电子邮件、JavaScript和CSV。您可以对任何基于文本的格式使用模板语言。

哦,还有一件事:让人类编辑XML是虐待狂!

二、变量

变量如下所示:{{ variable }}。当模板引擎遇到一个变量时,它会计算该变量并用结果替换它。变量名由字母数字字符和下划线("_"),但不能以下划线开头。圆点(".")也出现在变量节中,尽管这有一个特殊的含义,如下所示。重要的是,变量名中不能有空格或标点符号。

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

从技术上讲,当模板系统遇到一个点时,它会按以下顺序尝试以下查找:

  • 字典查找

  • 属性或方法查找

  • 数字索引查找

如果结果值是可调用的,则调用它时不带任何参数。调用的结果成为模板值。

此查找顺序会对覆盖字典查找的对象造成一些意外行为。例如,考虑以下试图在collections.defaultdict:

{% for k, v in defaultdict.items %}
    Do something with k and v here...
{% endfor %}

因为字典查找首先发生,所以该行为会启动并提供一个默认值,而不是使用预期的.items()方法。在这种情况下,考虑先转换为字典。

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

如果使用不存在的变量,模板系统将插入string_if_invalid选项,该选项设置为''(空字符串)默认情况下。

请注意模板表达式中的“bar”,如{{ foo.bar }}如果变量“bar”存在于模板上下文中,则将被解释为文字字符串,而不是使用变量“bar”的值。

以下划线开头的变量属性可能不会被访问,因为它们通常被认为是私有的。

三、过滤器(Filters)

可以通过以下方式修改显示变量过滤器.

过滤器看起来如下:{{ name|lower }}..这将显示{{ name }}变量后,通过lower过滤器,它将文本转换为小写。用管子(|)应用过滤器。

过滤器可以“链式”。将一个过滤器的输出应用到下一个过滤器。{{ text|escape|linebreaks }}是一个常见的成语,用于转义文本内容,然后将换行符转换为<p>标签。

有些过滤器采用论点。过滤器参数如下所示:{{ bio|truncatewords:30 }}..这将显示bio变量。

必须引用包含空格的筛选参数;例如,使用逗号和空格连接列表{{ list|join:", " }}.

Django提供了大约60个内置模板过滤器。你可以在内置滤波器参考..为了让您体验一下可用的内容,下面是一些更常用的模板过滤器:

default

如果变量为false或空,则使用给定的默认值。否则,使用变量的值。例如:

{{ value|default:"nothing" }}

如果value不提供或空,上面将显示“nothing”.

length返回值的长度。这既适用于字符串,也适用于列表。例如:

{{ value|length }}

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

filesizeformat

将值格式化为“人类可读的”文件大小(例如'13 KB''4.1 MB''102 bytes'等等)。例如:

{{ value|filesizeformat }}

如果value为123456789,输出为117.7 MB.

同样,这些只是几个例子;请参阅内置滤波器参考完整的名单。

您还可以创建自己的自定义模板筛选器;请参见自定义模板标记和过滤器.

Django的管理界面可以包含对所有模板标记和过滤器的完整引用,这些模板标记和过滤器都可以用于给定的站点。更多请见Django管理文档生成器

四、注释

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

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

{# greeting #}hello

注释可以包含任何模板代码,无效或无效。例如:

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

此语法只能用于单行注释(不允许在{##}(定界符)如果需要注释掉模板的多行部分,请参见comment标签。

五、模板继承

Django的模板引擎中最强大、也是最复杂的部分是模板继承。模板继承允许您构建一个基本的“骨架”模板,该模板包含站点的所有公共元素并定义blocks子模板可以覆盖。

从一个示例开始,最容易理解模板继承:

<!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>

这个模板,我们称之为base.html,定义一个简单的HTML框架文档,可以用于简单的两列页。这是“子”模板的工作,用内容填充空块。

在本例中,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”。

此时,模板引擎将注意到这三个block标签base.html并将这些块替换为子模板的内容。取决于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.htmlbase_sports.html..这些模板都扩展了base.html并包括特定章节的风格/设计。

  • 为每种类型的页面创建单独的模板,例如新闻文章或博客条目。这些模板扩展了适当的节模板。

这种方法最大限度地实现了代码重用,并使将项添加到共享内容区域(如区段范围的导航)变得更加容易。

以下是使用继承的一些技巧:

  • 如果你用{% extends %}在模板中,它必须是该模板中的第一个模板标记。否则,模板继承将无法工作。

  • 更多{% block %}基本模板中的标记更好。请记住,子模板不必定义所有父块,因此可以在多个块中填充合理的默认值,然后只定义稍后需要的块。多钩比少钩好。

  • 如果您发现自己在许多模板中复制内容,这可能意味着您应该将该内容移到{% block %}在父模板中。

  • 如果需要从父模板获取块的内容,则{{ block.super }}变量会起作用的。如果您想要添加到父块的内容而不是完全覆盖它,这是非常有用的。插入的数据{{ block.super }}将不会自动转义(请参阅下一节),因为如果有必要,它已经在父模板中转义了。

  • 外部创建的变量。{% block %}使用模板标记as语法不能在块内使用。例如,此模板不呈现任何内容:

{% trans "Title" as title %}
{% block content %}{{ title }}{% endblock %}

为了获得额外的可读性,您可以选择name给你的{% endblock %}标签。例如:

{% block content %}
...
{% endblock content %}
  • 在较大的模板中,此技术帮助您查看{% block %}标签被关闭了。

最后,请注意,您不能定义多个block同一模板中具有相同名称的标记。这种限制存在是因为块标记在“双向”方向上工作。也就是说,块标记不仅提供了一个可以填充的洞-它还定义了填充父母..如果有两个相似的名字block标记在模板中,该模板的父模板将不知道要使用哪个块的内容。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值