Django模板系统
一、Django模板系统基础
1.1 模板系统简介
Django模板系统是Django框架中用于生成动态HTML的核心组件,它实现了业务逻辑(Python代码)与展示逻辑(HTML)的分离。模板系统基于简单的文本格式,使用特殊的语法标记动态内容。
核心特点:
变量替换:使用
{{ variable }}
语法逻辑控制:使用
{% tag %}
语法可扩展性:支持自定义标签和过滤器
继承机制:支持模板继承,减少重复代码
1.2 基本语法规则
Django模板语言使用两种特殊符号:
变量:
{{ variable }}
用于显示变量值
示例:
{{ user.name }}
标签:
{% tag %}
用于执行逻辑控制
示例:
{% for item in list %}
重要规则:
点号(.)有特殊含义,查找顺序:
字典查找(
dict.key
)属性查找(
object.attribute
)方法调用(
object.method()
)列表索引(
list.0
)
如果变量不存在,模板系统会插入空字符串而非报错
模板中调用方法时不能传递参数
二、模板变量与过滤器
2.1 变量使用
变量可以来自视图函数传递的上下文,也可以是模板中的临时变量。
<p>用户名: {{ user.username }}</p>
<p>第一个朋友: {{ friends.0.name }}</p>
<p>当前时间: {{ now }}</p>
2.2 常用内置过滤器
过滤器用于在显示前对变量进行修改,语法为{{ variable|filter:arg }}
。
2.2.1 基础过滤器
过滤器 | 描述 | 示例 |
---|---|---|
default | 变量为False或空时使用默认值 | {{ value|default:"nothing" }} |
length | 返回值的长度 | {{ list|length }} |
filesizeformat | 格式化文件大小 | {{ 1024|filesizeformat }} → "1 KB" |
slice | 切片操作 | {{ "hello"|slice:"2:4" }} → "ll" |
2.2.2 字符串处理
过滤器 | 描述 | 示例 |
---|---|---|
lower | 转换为小写 | {{ "HELLO"|lower }} → "hello" |
upper | 转换为大写 | {{ "hello"|upper }} → "HELLO" |
truncatechars | 截断字符 | {{ "long text"|truncatechars:5 }} → "lon..." |
truncatewords | 截断单词 | {{ "long sentence"|truncatewords:1 }} → "long..." |
cut | 移除指定字符 | {{ "spaced"|cut:" " }} → "spaced" |
join | 连接列表 | {{ list|join:", " }} |
2.2.3 日期时间处理
{{ post.pub_date|date:"Y-m-d H:i:s" }}
{{ user.last_login|timeuntil }}
{{ event.start_time|timesince:event.end_time }}
常用日期格式化字符:
字符 | 描述 | 示例 |
---|---|---|
Y | 4位年份 | 2023 |
m | 2位月份 | 01-12 |
d | 2位日期 | 01-31 |
H | 24小时制 | 00-23 |
i | 分钟 | 00-59 |
s | 秒 | 00-59 |
2.2.4 安全相关
过滤器 | 描述 | 示例 |
---|---|---|
safe | 禁用HTML转义 | {{ html_content|safe }} |
escape | 转义HTML | {{ user_input|escape }} |
striptags | 去除HTML标签 | {{ "<b>text</b>"|striptags }} → "text" |
三、模板标签
3.1 控制流标签
3.1.1 for
循环
<ul>
{% for user in user_list %}<li>{{ forloop.counter }}. {{ user.name }}</li>
{% empty %}<li>暂无用户</li>
{% endfor %}
</ul>
forloop变量属性:
属性 | 描述 |
---|---|
counter | 当前循环次数(从1开始) |
counter0 | 当前循环次数(从0开始) |
revcounter | 反向循环次数(从1开始) |
revcounter0 | 反向循环次数(从0开始) |
first | 是否为第一次循环 |
last | 是否为最后一次循环 |
parentloop | 外层循环对象 |
3.1.2 if
条件判断
{% if user_list %}用户数: {{ user_list|length }}
{% elif black_list %}黑名单数: {{ black_list|length }}
{% else %}没有用户数据
{% endif %}
支持的运算符:
比较:
==
,!=
,<
,>
,<=
,>=
逻辑:
and
,or
,not
成员:
in
,not in
同一性:
is
,is not
3.2 其他常用标签
3.2.1 with
创建局部变量
{% with total=products|length %}产品总数: {{ total }}
{% endwith %}
3.2.2 csrf_token
跨站请求保护
<form method="post">{% csrf_token %}<!-- 表单内容 -->
</form>
3.2.3 url
反向解析URL
<a href="{% url 'app_name:view_name' arg1 arg2 %}">链接</a>
3.2.4 include
包含其他模板
{% include "header.html" %}
四、模板继承与组件化
4.1 模板继承
基础模板(base.html):
<!DOCTYPE html>
<html>
<head><title>{% block title %}默认标题{% endblock %}</title>{% block css %}{% endblock %}
</head>
<body>{% block content %}<!-- 默认内容 -->{% endblock %}{% block js %}{% endblock %}
</body>
</html>
子模板(child.html):
{% extends "base.html" %}{% block title %}子页面标题{% endblock %}{% block css %}
<link rel="stylesheet" href="style.css">
{% endblock %}{% block content %}
<h1>这是子页面内容</h1>
{% endblock %}
4.2 静态文件处理
{% load static %}<!-- 图片 -->
<img src="{% static 'images/logo.png' %}" alt="Logo"><!-- CSS -->
<link rel="stylesheet" href="{% static 'css/style.css' %}"><!-- JavaScript -->
<script src="{% static 'js/app.js' %}"></script>
高级用法:
{% load static %}
{% get_static_prefix as STATIC_PREFIX %}<img src="{{ STATIC_PREFIX }}images/icon.png">
五、自定义标签和过滤器
5.1 创建自定义过滤器
在app目录下创建
templatetags
目录和__init__.py
文件创建过滤器文件,如
my_filters.py
:
from django import templateregister = template.Library()@register.filter(name='cut')
def cut(value, arg):"""移除字符串中的所有指定字符"""return value.replace(arg, '')@register.filter
def add_str(value, arg):"""添加后缀"""return f"{value}{arg}"
在模板中使用:
{% load my_filters %}{{ "spaced text"|cut:" " }} <!-- 输出: "spacedtext" -->
{{ "price"|add_str:"$" }} <!-- 输出: "price$" -->
5.2 创建自定义标签
5.2.1 Simple Tag
@register.simple_tag
def current_time(format_string):return datetime.datetime.now().strftime(format_string)
模板中使用:
{% current_time "%Y-%m-%d %H:%M:%S" %}
5.2.2 Inclusion Tag
@register.inclusion_tag('result.html')
def show_results(n):n = max(1, int(n))return {'items': range(1, n+1)}
result.html
:
<ul>
{% for item in items %}<li>项目 {{ item }}</li>
{% endfor %}
</ul>
模板中使用:
{% show_results 5 %}
六、最佳实践与常见问题
6.1 最佳实践
模板组织:
将模板按功能模块划分
公共部分提取为基模板
重复部分提取为组件
性能优化:
避免在模板中进行复杂计算
使用
{% with %}
缓存频繁访问的变量合理使用
{% include %}
安全性:
对用户输入内容使用
escape
或striptags
谨慎使用
safe
过滤器所有POST表单包含
{% csrf_token %}
6.2 常见问题
变量查找失败:
检查变量名拼写
确认视图函数是否正确传递了变量
使用
default
过滤器提供默认值
模板继承问题:
确保
{% extends %}
是模板的第一个标签检查基模板路径是否正确
确认所有必要的
{% block %}
都已定义
静态文件加载失败:
确认
STATIC_URL
设置正确检查文件是否在
STATICFILES_DIRS
目录中确保
{% load static %}
在文件顶部
通过掌握这些Django模板系统的知识,您将能够高效地构建动态、可维护的Web页面,同时保持代码的整洁和可扩展性。