pin_drop当前位置:知识文库 ❯ 图文

Django Template模板完整教程:模板语言与继承实战 - 零基础入门

一、Template模板概述

Django模板引擎(Django Template Language,简称DTL)用于生成动态HTML页面。通过模板标签和变量将后端数据渲染到页面中,实现前后端数据的分离与展示。

模板继承机制允许定义基础布局,子模板覆盖特定区块,大幅减少重复代码。Django模板语言提供了变量、标签、过滤器和注释四种核心语法,是Django Web开发中不可或缺的组件。


二、模板语法基础

Django模板语言由四种基本语法构成:

语法 说明 示例
{{ var }} 变量输出 {{ title }}
{{ var|filter }} 过滤器 {{ name|upper }}
{% tag %} 模板标签 {% if condition %}
{# comment #} 单行注释 {# 这是注释 #}
{% comment %} 多行注释 {% comment %}...{% endcomment %}

三、常用模板标签

模板标签用于在模板中执行逻辑操作,如条件判断、循环遍历、包含子模板等。

标签 说明
{% if %}{% endif %} 条件判断
{% for %}{% endfor %} 循环遍历
{% extends %} 模板继承,指定父模板
{% block %}{% endblock %} 定义可覆盖的区块
{% include %} 包含子模板
{% url %} URL反向解析
{% load %} 加载自定义标签库
{% csrf_token %} CSRF令牌保护
{% with %}{% endwith %} 定义变量别名

四、常用过滤器

过滤器用于在模板中格式化变量值,通过管道符 | 连接变量和过滤器。

过滤器 说明 示例
default 设置默认值 {{ value|default:'N/A' }}
length 获取长度 {{ list|length }}
upper/lower 大小写转换 {{ name|upper }}
date 日期格式化 {{ dt|date:'Y-m-d' }}
truncatechars 截断字符并添加省略号 {{ text|truncatechars:50 }}
safe 跳过HTML自动转义 {{ html|safe }}
join 连接列表元素 {{ list|join:', ' }}
add 加法运算 {{ value|add:5 }}

五、模板继承实战

模板继承是Django模板系统的核心特性。通过定义基础模板(base.html),然后在子模板中使用 {% extends %}{% block %} 实现布局复用。

基础模板 base.html

代码示例

<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}My Site{% endblock %}</title>
</head>
<body>
    <nav>
        <a href="{% url 'index' %}">首页</a>
        <a href="{% url 'about' %}">关于</a>
    </nav>
    <main>
        {% block content %}{% endblock %}
    </main>
    <footer>
        {% block footer %}© 2024{% endblock %}
    </footer>
</body>
</html>

子模板 article_list.html

代码示例

<!-- templates/article_list.html -->
{% extends "base.html" %}

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

{% block content %}
<h1>文章列表</h1>
{% for article in articles %}
    <article>
        <h2>{{ article.title }}</h2>
        <p>{{ article.content|truncatechars:100 }}</p>
        <span>{{ article.created_at|date:'Y-m-d' }}</span>
    </article>
{% empty %}
    <p>暂无文章</p>
{% endfor %}
{% endblock %}

小贴士

模板继承可以多层嵌套。例如 base.html -> content_base.html -> article_list.html,这样可以实现更细粒度的布局控制。


六、条件判断与循环

条件判断和循环是模板中最常用的逻辑控制结构,下面通过一个完整的仪表盘模板示例来演示:

代码示例

<!-- templates/dashboard.html -->
{% extends "base.html" %}

{% block content %}
<h1>仪表盘</h1>

{# 条件判断 #}
{% if user.is_authenticated %}
    <p>欢迎, {{ user.username }}!</p>
    {% if user.is_staff %}
        <a href="/admin/">管理后台</a>
    {% endif %}
{% else %}
    <p>请先<a href="{% url 'login' %}">登录</a></p>
{% endif %}

{# 循环遍历 #}
<table>
    {% for item in items %}
        <tr class="{% cycle 'odd' 'even' %}">
            <td>{{ forloop.counter }}</td>
            <td>{{ item.name }}</td>
            <td>{{ item.price|floatformat:2 }}</td>
        </tr>
    {% endfor %}
</table>

{# 列表长度 #}
<p>总项目数: {{ items|length }}</p>
{% endblock %}

forloop 变量

在循环中,Django提供了 forloop 变量来获取循环状态:

  • forloop.counter:当前循环次数,从1开始计数

  • forloop.counter0:当前循环次数,从0开始计数

  • forloop.revcounter:剩余循环次数,从总数开始递减

  • forloop.first:是否为第一次循环(布尔值)

  • forloop.last:是否为最后一次循环(布尔值)


七、自定义模板标签和过滤器

当内置标签和过滤器无法满足需求时,可以创建自定义模板标签和过滤器。

创建自定义过滤器

代码示例

# blog/templatetags/blog_extras.py
from django import template

register = template.Library()

@register.filter
def multiply(value, arg):
    """乘法过滤器"""
    try:
        return float(value) * float(arg)
    except (ValueError, TypeError):
        return 0

@register.filter
def currency(value):
    """货币格式过滤器"""
    try:
        return f'¥{float(value):.2f}'
    except (ValueError, TypeError):
        return '¥0.00'

@register.inclusion_tag('blog/sidebar.html')
def show_sidebar():
    """包含标签:渲染侧边栏"""
    from blog.models import Category
    categories = Category.objects.all()
    return {'categories': categories}

在模板中使用自定义标签

代码示例

{% load blog_extras %}

{{ product.price|currency }}
{{ quantity|multiply:price }}
{% show_sidebar %}

注意:自定义标签文件必须放在应用的 templatetags/ 目录下,且该目录必须包含 __init__.py 文件。修改后需要重启Django服务器才能生效。


八、注意事项与最佳实践

注意:模板变量中的点号会按字典、属性、方法、列表索引的顺序查找,这是Django模板的变量解析规则。

注意:模板中不能执行任意Python代码,这是设计限制也是安全特性,防止模板中出现危险操作。

注意safe 过滤器会跳过自动转义,仅在信任内容时使用,否则可能导致XSS攻击。

注意:模板文件默认放在应用目录的 templates/ 下,需要在 TEMPLATES 设置中正确配置。

模板继承与包含对比

方式 语法 说明 适用场景
extends {% extends "base.html" %} 继承整个布局 页面整体布局
include {% include "nav.html" %} 包含片段 可复用组件

九、练习题

练习一

编写一个基础模板 base.html,包含导航栏(首页、关于、联系我们)和页脚(版权信息和备案号),然后创建两个子模板(首页和关于页)继承它。

练习二

编写一个自定义过滤器,将Markdown文本转换为HTML(使用markdown库),并在模板中使用该过滤器渲染文章内容。

常见问题

模板继承和模板包含有什么区别?

extends 用于继承整个页面布局,子模板可以覆盖父模板中定义的 block 区块。include 用于插入一个独立的模板片段,适合复用导航栏、侧边栏等小组件。两者可以结合使用。

如何在模板中调用对象的方法?

使用点号语法即可调用无参数的方法,如 {{ article.get_status_display }}。模板中调用方法不需要加括号,只能调用不接受参数的方法。

safe过滤器有什么安全风险?

safe过滤器会跳过HTML自动转义,如果内容来自用户输入且未经过滤,可能导致XSS(跨站脚本)攻击。只对来自可信来源的HTML内容使用safe过滤器,如富文本编辑器生成的内容。

自定义模板标签创建后为什么不生效?

自定义标签文件必须放在应用的 templatetags/ 目录下(包含 __init__.py),且修改后需要重启Django开发服务器。确保在模板中使用 {% load %} 标签加载了正确的标签库。

forloop.empty 是什么?如何使用?

forloop.empty 是Django 3.2+引入的特性,当循环的查询集为空时返回True。但在实际开发中,更推荐使用 {% empty %} 标签来处理空列表情况,语法更简洁。

标签: Django Template 模板语言 模板继承 过滤器 自定义标签 Python

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: Django View视图完整教程:函数视图与类视图详解 - 零基础入门指南 下一篇: Django URL路由详解 - path、re_path与反向解析完整教程

poll相关推荐