pin_drop当前位置:知识文库 ❯ 图文
Django Template模板完整教程:模板语言与继承实战 - 零基础入门
一、Template模板概述
Django模板引擎(Django Template Language,简称DTL)用于生成动态HTML页面。通过模板标签和变量将后端数据渲染到页面中,实现前后端数据的分离与展示。
模板继承机制允许定义基础布局,子模板覆盖特定区块,大幅减少重复代码。Django模板语言提供了变量、标签、过滤器和注释四种核心语法,是Django Web开发中不可或缺的组件。
二、模板语法基础
Django模板语言由四种基本语法构成:
三、常用模板标签
模板标签用于在模板中执行逻辑操作,如条件判断、循环遍历、包含子模板等。
四、常用过滤器
过滤器用于在模板中格式化变量值,通过管道符 | 连接变量和过滤器。
五、模板继承实战
模板继承是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设置中正确配置。
模板继承与包含对比
九、练习题
练习一
编写一个基础模板 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 %} 标签来处理空列表情况,语法更简洁。
本文涉及AI创作
内容由AI创作,请仔细甄别