Skip to content

第7章:模板系统

7.2 模板继承

基础模板创建

模板继承是Django模板系统中最强大的功能之一。它允许你创建一个基础模板,其他模板可以继承并扩展它,避免重复代码。

首先创建一个基础模板base.html

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}我的网站{% endblock %}</title>
    {% block extra_css %}{% endblock %}
</head>
<body>
    <header>
        <nav>
            <ul>
                <li><a href="/">首页</a></li>
                <li><a href="/articles/">文章</a></li>
                <li><a href="/about/">关于</a></li>
            </ul>
        </nav>
    </header>

    <main>
        {% block content %}
        <!-- 子模板将在这里填充内容 -->
        {% endblock %}
    </main>

    <footer>
        <p>&copy; 2025 我的网站. 保留所有权利.</p>
    </footer>

    {% block extra_js %}{% endblock %}
</body>
</html>

块(block)标签

block标签定义了可以在子模板中被覆盖的部分。基础模板中可以定义多个块:

html
<!-- base.html -->
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}默认标题{% endblock %}</title>
    {% block meta %}{% endblock %}
    {% block css %}{% endblock %}
</head>
<body>
    <div id="header">
        {% block header %}
        <h1>我的网站</h1>
        {% endblock %}
    </div>

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

    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">首页</a></li>
            <li><a href="/blog/">博客</a></li>
        </ul>
        {% endblock %}
    </div>

    <div id="footer">
        {% block footer %}
        <p>版权所有 &copy; 2025</p>
        {% endblock %}
    </div>
</body>
</html>

模板继承链

子模板使用extends标签继承基础模板,并使用block标签来覆盖或扩展父模板中的块:

html
<!-- blog_list.html -->
{% extends "base.html" %}

{% block title %}博客列表 - {{ block.super }}{% endblock %}

{% block content %}
    <h2>最新文章</h2>
    {% for article in articles %}
        <article>
            <h3><a href="{{ article.get_absolute_url }}">{{ article.title }}</a></h3>
            <p>{{ article.summary }}</p>
            <p class="meta">发布于 {{ article.publish_date|date:"Y-m-d" }}</p>
        </article>
    {% empty %}
        <p>暂无文章。</p>
    {% endfor %}
{% endblock %}

{% block sidebar %}
    {{ block.super }}
    <div class="widget">
        <h3>分类</h3>
        <ul>
            {% for category in categories %}
                <li><a href="{{ category.get_absolute_url }}">{{ category.name }}</a></li>
            {% endfor %}
        </ul>
    </div>
{% endblock %}

实际示例:博客布局

以下是一个完整的博客布局示例:

基础模板 base.html

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}我的博客{% endblock %}</title>
    <link rel="stylesheet" href="/static/css/style.css">
    {% block extra_head %}{% endblock %}
</head>
<body>
    <div class="container">
        <header class="header">
            {% block header %}
            <h1><a href="/">我的博客</a></h1>
            <nav>
                <ul>
                    <li><a href="/">首页</a></li>
                    <li><a href="/categories/">分类</a></li>
                    <li><a href="/tags/">标签</a></li>
                    <li><a href="/about/">关于</a></li>
                </ul>
            </nav>
            {% endblock %}
        </header>

        <div class="main-content">
            {% block content %}{% endblock %}
        </div>

        <aside class="sidebar">
            {% block sidebar %}
            <div class="widget">
                <h3>关于我</h3>
                <p>这是一个关于我的简短介绍。</p>
            </div>
            {% endblock %}
        </aside>

        <footer class="footer">
            {% block footer %}
            <p>&copy; 2025 我的博客. 保留所有权利.</p>
            {% endblock %}
        </footer>
    </div>
</body>
</html>

文章列表模板 article_list.html

html
{% extends "base.html" %}

{% block title %}文章列表 - {{ block.super }}{% endblock %}

{% block content %}
<div class="article-list">
    <h2>最新文章</h2>
    {% for article in articles %}
    <article class="article-item">
        <h3><a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a></h3>
        <div class="article-meta">
            <span>作者:{{ article.author }}</span>
            <span>发布于:{{ article.publish_date|date:"Y-m-d H:i" }}</span>
        </div>
        <div class="article-summary">
            <p>{{ article.content|truncatewords:50 }}</p>
        </div>
    </article>
    {% empty %}
    <p>暂无文章。</p>
    {% endfor %}
</div>
{% endblock %}

文章详情模板 article_detail.html

html
{% extends "base.html" %}

{% block title %}{{ article.title }} - {{ block.super }}{% endblock %}

{% block content %}
<article class="article-detail">
    <h2>{{ article.title }}</h2>
    <div class="article-meta">
        <span>作者:{{ article.author }}</span>
        <span>发布于:{{ article.publish_date|date:"Y-m-d H:i" }}</span>
        <span>分类:{{ article.category }}</span>
    </div>
    <div class="article-content">
        {{ article.content|linebreaks }}
    </div>
    <div class="article-tags">
        {% for tag in article.tags.all %}
        <span class="tag">{{ tag.name }}</span>
        {% endfor %}
    </div>
</article>
{% endblock %}

小结

模板继承是Django模板系统的核心特性:

  1. ✅ 使用extends标签继承基础模板
  2. ✅ 通过block标签定义可覆盖的区域
  3. ✅ 利用block.super保留父模板内容
  4. ✅ 实现代码复用,减少重复编写
  5. ✅ 统一网站布局和样式

合理使用模板继承能够显著提高前端开发效率。

下一篇

我们将学习自定义模板过滤器和标签。

7.3 模板自定义 →

目录

返回课程目录

Released under the Apache 2.0 License.