Django 模板(完整教程)

Django 模板:让前端与后端“心有灵犀”

你有没有遇到过这样的场景?写完一个功能,数据能跑通,但页面却像一张白纸,或者格式乱七八糟?这背后,往往是因为你还没掌握 Django 模板系统。它就像是 Django 的“视觉中枢”——负责把数据变成用户看得懂、用得顺的网页。

Django 模板不是简单的 HTML 文件拼接,而是一套逻辑清晰、功能强大的动态渲染机制。它让你既能保持 HTML 的结构美感,又能灵活注入 Python 逻辑,真正实现“前后端分离”的优雅协作。今天,我们就从零开始,带你一步步掌握 Django 模板的核心能力。


什么是 Django 模板?

Django 模板是一种基于文本的模板引擎,专门用于生成 HTML、XML 或其他文本格式。你可以把它想象成一个“网页工厂”:你提供“模具”(模板文件),再塞入“原材料”(数据),它就自动输出完整的网页。

它的核心价值在于:将业务逻辑与页面展示逻辑分离。开发者专注写代码,设计师专注做 UI,互不干扰,协作更高效。

在 Django 中,模板文件通常以 .html 为扩展名,放在项目目录下的 templates 文件夹中。Django 会自动加载这些文件,并根据视图函数传递的数据进行动态渲染。


创建模板文件与基本结构

要使用 Django 模板,第一步是创建模板文件。假设你有一个博客项目,想展示一篇标题为“Django 入门指南”的文章。

首先,在你的应用目录中创建 templates 文件夹,比如 blog/templates/blog/,然后新建一个文件:article.html

<!-- article.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>{{ article_title }}</title>
</head>
<body>
    <h1>{{ article_title }}</h1>
    <p>作者:{{ author_name }}</p>
    <div class="content">
        {{ article_content }}
    </div>
</body>
</html>

注释:

  • {{ article_title }} 是一个变量占位符,Django 会在渲染时替换为实际值。
  • {{ author_name }}{{ article_content }} 同理。
  • <!DOCTYPE html> 声明文档类型,确保浏览器正确解析。
  • <title> 标签中的 {{ article_title }} 会动态更新页面标题,非常实用。

这个模板现在还不能直接用,必须在视图中加载并传递数据。


在视图中使用模板:render 函数

Django 提供了 render 函数,用于将模板与数据结合,返回一个 HTTP 响应。

from django.shortcuts import render

def show_article(request):
    # 准备要传给模板的数据
    context = {
        'article_title': 'Django 模板入门指南',
        'author_name': '小明',
        'article_content': 'Django 模板是构建动态网页的核心工具。它支持变量、标签和过滤器,让开发者轻松控制页面输出。'
    }
    
    # 使用 render 函数渲染模板,并返回响应
    return render(request, 'blog/article.html', context)

注释:

  • render(request, template_name, context) 是 Django 提供的标准函数。
  • request 是 HTTP 请求对象,必须传入。
  • template_name 是模板文件的路径,从 templates 根目录开始写,用斜杠分隔。
  • context 是一个字典,包含所有要传递给模板的数据。
  • 调用后,Django 会自动查找模板文件,替换变量,返回完整 HTML 响应。

现在访问对应 URL,就能看到动态生成的网页了。


模板标签:控制流程的“指挥棒”

变量只是基础,真正让 Django 模板强大的是标签(Tags)。它们就像编程中的 if-else、for 循环,能控制模板的执行流程。

使用 if 标签实现条件渲染

比如你想根据文章状态显示“已发布”或“草稿”标签:

<!-- 在 article.html 中添加 -->
{% if is_published %}
    <span class="status published">已发布</span>
{% else %}
    <span class="status draft">草稿</span>
{% endif %}

注释:

  • {% if ... %}{% endif %} 构成一个条件块。
  • is_published 是布尔值,True 显示“已发布”,False 显示“草稿”。
  • 模板中不支持复杂的逻辑判断,仅支持简单比较(如 ==!=),适合展示场景。

使用 for 标签遍历列表

假设你想展示文章的多个标签:

<!-- 在 article.html 中添加 -->
<ul class="tags">
    {% for tag in tags %}
        <li>{{ tag }}</li>
    {% endfor %}
</ul>

注释:

  • for 标签用于遍历可迭代对象(如列表、元组)。
  • tag 是当前循环的变量名,可自定义。
  • 每次循环输出一个 <li>,最终生成标签列表。
  • endfor 必须闭合,否则模板渲染会出错。

模板过滤器:美化数据的“化妆师”

变量传进去了,但格式可能不够理想。比如时间显示为 2024-04-05 14:30:22,用户更希望看到“2024年4月5日 14:30”。这时,过滤器就派上用场了。

Django 内置了丰富的过滤器,语法是:{{ value|filter_name:argument }}

常用过滤器示例

<!-- 显示发布时间 -->
<p>发布时间:{{ publish_time|date:"Y年m月d日 H:i" }}</p>

<!-- 转换为大写 -->
<p>标题:{{ article_title|upper }}</p>

<!-- 截取字符串 -->
<p>摘要:{{ article_content|truncatewords:10 }}</p>

<!-- 安全转义 HTML(防止 XSS) -->
<div>{{ user_input|safe }}</div>

注释:

  • date 过滤器支持多种格式,"Y年m月d日 H:i" 会输出“2024年04月05日 14:30”。
  • upper 将字符串转为大写。
  • truncatewords 截取前 10 个单词,适合摘要。
  • safe 表示内容可信,允许 HTML 渲染,但需谨慎使用,避免安全风险。

模板继承:打造统一的网站结构

如果你有多个页面(如首页、文章页、关于页),每个页面都有相同的头部、导航栏、页脚,重复写 HTML 会非常低效。

Django 提供了模板继承机制,让你只需定义一个“母版”模板,其他页面继承它,只需覆盖特定区域。

创建基础模板 base.html

<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}我的 Django 网站{% endblock %}</title>
    <link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
    <!-- 顶部导航 -->
    <header>
        <nav>
            <a href="/">首页</a>
            <a href="/about/">关于</a>
            <a href="/blog/">博客</a>
        </nav>
    </header>

    <!-- 主要内容区域 -->
    <main>
        {% block content %}
        <!-- 子模板可覆盖此区域 -->
        {% endblock %}
    </main>

    <!-- 页脚 -->
    <footer>
        &copy; 2024 我的网站. 保留所有权利。
    </footer>
</body>
</html>

注释:

  • {% block title %}{% block content %} 是“占位块”,子模板可覆盖。
  • blockendblock 成对出现,定义可替换区域。
  • title 块默认值为“我的 Django 网站”,子模板可改写。

继承基础模板的子模板

<!-- templates/blog/article.html -->
{% extends 'base.html' %}

{% block title %}Django 模板详解{% endblock %}

{% block content %}
    <h1>{{ article_title }}</h1>
    <p>作者:{{ author_name }}</p>
    <div class="article-content">
        {{ article_content|linebreaks }}
    </div>
{% endblock %}

注释:

  • {% extends 'base.html' %} 表示继承 base.html
  • block titleblock content 会覆盖父模板中的对应块。
  • linebreaks 过滤器将换行符转为 <br>,适合纯文本内容。

实际案例:搭建一个简单博客列表页

我们来实战一个完整案例:展示多篇文章列表。

视图函数

from django.shortcuts import render

def article_list(request):
    articles = [
        {
            'title': 'Django 模板入门',
            'author': '小明',
            'date': '2024-04-05',
            'tags': ['Django', '模板', 'Python'],
            'published': True
        },
        {
            'title': 'REST API 设计',
            'author': '小红',
            'date': '2024-04-03',
            'tags': ['API', 'JSON'],
            'published': False
        }
    ]
    
    return render(request, 'blog/list.html', {'articles': articles})

模板文件 list.html

{% extends 'base.html' %}

{% block title %}文章列表{% endblock %}

{% block content %}
    <h2>最新文章</h2>
    <ul class="article-list">
        {% for article in articles %}
            <li class="article-item">
                <h3><a href="/article/{{ forloop.counter }}/">{{ article.title }}</a></h3>
                <p>作者:{{ article.author }} | 发布时间:{{ article.date|date:"Y年m月d日" }}</p>
                {% if article.published %}
                    <span class="status published">已发布</span>
                {% else %}
                    <span class="status draft">草稿</span>
                {% endif %}
                <ul class="tags">
                    {% for tag in article.tags %}
                        <li>{{ tag }}</li>
                    {% endfor %}
                </ul>
            </li>
        {% endfor %}
    </ul>
{% endblock %}

注释:

  • forloop.counter 是循环索引,从 1 开始。
  • 通过 forloop 可访问循环状态,如 counter, first, last
  • 模板结构清晰,逻辑分明,易于维护。

总结:Django 模板让开发更高效

Django 模板不是“可有可无”的功能,而是 Django 架构中不可或缺的一环。它通过变量、标签、过滤器和继承机制,实现了动态内容渲染与结构复用的完美平衡。

从简单的变量替换,到复杂的条件判断与循环遍历,再到跨页面的结构统一,Django 模板让你既能快速搭建原型,也能构建可维护的中大型项目。

掌握它,意味着你真正迈入了 Django 的“全栈”世界。别再把 HTML 当作静态文件,把它当作一个“可编程的界面”,你会发现,前后端协作,原来可以如此顺畅。