Skip to content

Django 模板标签

Django 模板系统是其 MVT (Model-View-Template) 架构中的关键一环,负责将数据与表示逻辑分离,生成最终呈现给用户的 HTML。在这个系统中,模板标签扮演着至关重要的角色。它们不仅仅是简单的占位符,更是嵌入在模板中的逻辑控制器,使得开发者能够在 HTML 结构中执行编程逻辑、控制流程、加载资源,从而构建出功能丰富、动态交互的网页。理解并熟练运用模板标签,是高效进行 Django 开发的基础。

什么是 Django 模板标签?

Django 模板标签是被两个花括号和百分号包围起来的标记,其基本语法形式为 {% tag %}。与用于输出变量值的模板变量 {{ variable }} 不同,模板标签执行更复杂的操作。它们可以创建文本输出、控制流程(如循环和条件判断)、加载外部信息或调用特定的模板函数。本质上,标签提供了一种在模板层面上执行有限逻辑的方式,使得模板保持相对简洁,同时又能处理动态内容的需求。例如,{% for item in item_list %} 就是一个典型的模板标签,用于迭代一个列表。

常用内置标签详解

Django 内置了丰富的模板标签,覆盖了 Web 开发中的常见场景。掌握这些核心标签对于编写高效、可维护的模板至关重要。

for 标签

for 标签用于迭代序列中的每一项,如列表、元组或字典。这是构建动态列表、表格等元素的常用方法。

案例: 假设视图传递了一个名为 article_list 的文章列表到模板中,我们可以使用 for 标签来显示每篇文章的标题:

html
{% for article in article_list %}
    <h2>{{ article.title }}</h2>
    <p>{{ article.summary }}</p>
{% endfor %}

for 标签还可以带有一个可选的 {% empty %} 子句,当迭代的序列为空或不存在时,会执行 empty 块内的内容。

html
{% for article in article_list %}
    <h2>{{ article.title }}</h2>
{% empty %}
    <p>暂时没有文章发布。</p>
{% endfor %}

for 循环内部,可以使用 forloop 变量来获取循环的状态信息,例如 forloop.counter (当前迭代次数,从 1 开始),forloop.first (是否为第一次迭代),forloop.last (是否为最后一次迭代)。

if/elif/else 标签

if 系列标签用于执行条件判断,根据表达式的真假来决定渲染哪部分模板内容。这对于根据用户状态、数据属性等显示不同内容非常有用。

案例: 根据用户是否登录,显示不同的欢迎信息:

html
{% if user.is_authenticated %}
    <p>欢迎回来, <span v-pre>{{ user.username }}</span>!</p>
    <a href="{% url 'logout' %}">退出</a>
{% else %}
    <p>您好,游客!</p>
    <a href="{% url 'login' %}">登录</a>
{% endif %}

if 标签支持 and, or, not 逻辑运算符以及常见的比较操作符(==, !=, <, >, <=, >=)。可以使用 elif 来添加更多的条件分支。

html
{% if score >= 90 %}
    <p>优秀</p>
{% elif score >= 60 %}
    <p>及格</p>
{% else %}
    <p>需要努力</p>
{% endif %}

with 标签

with 标签用于将一个复杂的变量或表达式的结果缓存到一个简单的变量名下。这可以提高模板的可读性,有时也能略微提升性能,避免重复计算或访问。

案例: 假设需要多次访问一个嵌套较深或计算得到的属性:

html
{% with total=business.order_set.count %}
    <p>总订单数: {{ total }}</p>
    {% if total > 100 %}
        <p>业务繁忙!</p>
    {% endif %}
{% endwith %}

在这个例子中,business.order_set.count 的结果被赋给了 total 变量,在 with 块内部可以直接使用 total

url 标签

url 标签是 Django 中处理 URL 的推荐方式。它根据 urls.py 中定义的 URL 模式名称动态生成 URL 路径,避免了在模板中硬编码 URL,使得 URL 结构变更时维护更加方便。

案例: 生成一个指向名为 article_detail 的视图的链接,该视图需要一个 article_id 参数:

html
<a href="{% url 'article_detail' article.id %}">阅读全文</a>

如果 URL 模式不需要参数,则直接写名称:

html
<a href="{% url 'homepage' %}">返回首页</a>

使用 url 标签可以确保生成的链接始终与当前的 URL 配置保持一致。

load 标签

load 标签用于加载自定义的模板标签库或 Django 内置的标签库。在使用非默认加载的标签或过滤器之前,必须先使用 load 加载它们所在的库。

案例: 加载 Django 内置的 static 标签库,以便后续使用 static 标签:

html
{% load static %}

如果需要加载自定义的标签库(假设名为 my_custom_tags),则写作:

html
{% load my_custom_tags %}

static 标签

static 标签(需要先 {% load static %})用于生成指向静态文件(如 CSS、JavaScript、图片)的 URL。它会根据 settings.py 中的 STATIC_URL 设置来构建正确的路径。

案例: 在 HTML 中引入一个 CSS 文件和一个 JavaScript 文件:

html
{% load static %}
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<script src="{% static 'js/main.js' %}"></script>
<img src="{% static 'images/logo.png' %}" alt="Logo">

这确保了即使 STATIC_URL 发生变化,静态文件的引用也能自动更新。

csrf_token 标签

csrf_token 标签用于在 HTML 表单中插入一个隐藏的 input 字段,其值为 CSRF (Cross-Site Request Forgery) 令牌。这是 Django 防止 CSRF 攻击的关键机制,对于任何会修改数据的 POST 表单,都应该包含此标签。

案例: 在一个登录表单中使用 csrf_token

html
<form method="post">
    {% csrf_token %}
    <label for="username">用户名:</label>
    <input type="text" id="username" name="username">
    <label for="password">密码:</label>
    <input type="password" id="password" name="password">
    <button type="submit">登录</button>
</form>

extends 标签

extends 标签用于实现模板继承。它必须是模板文件中的第一个标签。它指定了当前模板继承自哪个父模板(基础模板)。子模板可以覆盖父模板中定义的 block

案例: 一个子模板 child.html 继承自 base.html

html
{% extends "base.html" %}

{% block title %}我的页面标题{% endblock %}

{% block content %}
    <p>这里是子页面的特定内容。</p>
{% endblock %}

block 标签

block 标签与 extends 标签配合使用,在父模板中定义一些可以被子模板覆盖的区域。子模板可以使用相同名称的 block 标签来填充或重写这些区域的内容。

案例: 在父模板 base.html 中定义块:

html
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}默认标题{% endblock %}</title>
</head>
<body>
    <header>...</header>
    <main>
        {% block content %}
        <!-- 默认内容或留空 -->
        {% endblock %}
    </main>
    <footer>...</footer>
</body>
</html>

子模板通过定义同名的 block 来填充这些区域,如上一个 extends 案例所示。

include 标签

include 标签用于将另一个模板文件的内容包含到当前模板中。这对于重用模板片段(如页眉、页脚、侧边栏)非常有用。

案例: 在主模板中包含一个页脚模板 footer.html

html
<body>
    ...
    {% include "includes/footer.html" %}
</body>

可以传递额外的上下文给被包含的模板:

html
{% include "includes/sidebar.html" with user=request.user %}

模板标签的逻辑流程示例

我们可以使用图示来更清晰地理解像 if/elif/else 这样的控制流标签是如何工作的。下面是一个简单的 Mermaid 流程图,展示了其决策过程:

这个图示说明了 Django 模板引擎如何根据条件的真假,选择性地渲染模板的不同部分。for 循环的逻辑类似,会根据序列是否为空以及是否还有下一个元素来决定执行循环体或 empty 块。

小结

Django 模板标签是连接后端数据逻辑与前端展示的桥梁。通过 for 进行迭代,if 进行条件判断,url 动态生成链接,static 管理静态资源,extendsblock 实现布局继承,include 重用模板片段,以及 csrf_token 保障安全,开发者可以构建出结构清晰、易于维护且功能强大的动态 Web 应用。熟练掌握这些内置标签的用法,并理解其背后的工作原理,对于提升 Django 开发效率和代码质量至关重要。

参考资料