4、模板系统:模板语法、变量与过滤器、模板继承、静态文件加载、自定义过滤器
模板系统,说白了就是 Django 用来生成 HTML 的那套工具。你想想看,如果每个页面都手写死 HTML,那改个网站标题都得翻遍所有文件,多累啊。Django 的模板引擎就是来解决这个问题的——它让你把数据塞进 HTML 里,还能复用布局,省心不少。
我个人习惯把模板当成「带占位符的 HTML」。你写一个骨架,Django 帮你把肉填上去。嗯,咱们一步步来看。
4.1 模板语法:花括号里的秘密
Django 模板语法很简单,就三种花括号:
{{ 变量 }}—— 输出变量值{% 标签 %}—— 执行逻辑(循环、判断等){# 注释 #}—— 注释,不会输出到页面
举个例子,你在视图里传了个 name 变量:
<h1>你好,{{ name }}!</h1>
如果 name = "张三",页面就会显示「你好,张三!」。就这么简单。
{{ user.name }} 会先尝试字典键,再尝试属性,最后尝试列表索引。我刚开始学的时候老搞混,后来发现它自动帮你试,挺贴心的。
4.2 变量与过滤器:给数据化个妆
变量直接输出没问题,但有时候你想改改格式。比如日期太长了,想截短一点;或者字符串全大写。这时候过滤器就派上用场了。
过滤器的写法是 {{ 变量|过滤器 }},可以链式调用:
{{ my_date|date:"Y-m-d" }}
{{ my_text|upper|truncatewords:5 }}
常用的内置过滤器我列一下:
| 过滤器 | 作用 | 示例 |
|---|---|---|
date |
格式化日期 | {{ now|date:"Y-m-d H:i" }} |
default |
变量为空时显示默认值 | {{ name|default:"访客" }} |
length |
返回列表/字符串长度 | {{ items|length }} |
safe |
标记为安全 HTML,不转义 | {{ html_content|safe }} |
join |
用指定字符连接列表 | {{ list|join:", " }} |
|safe。我曾经有个项目,用户提交的富文本内容没加 safe,结果所有 <b> 标签都显示成纯文本了,排查了半天。
4.3 模板继承:别再复制粘贴了
做网站最烦的是什么?每个页面都有导航栏、页脚、侧边栏,难道每个模板都写一遍?当然不。模板继承就是干这个的。
你写一个「父模板」,里面挖几个坑(block),子模板来填坑。比如 base.html:
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}默认标题{% endblock %}</title>
</head>
<body>
<nav>...导航栏...</nav>
<div id="content">
{% block content %}{% endblock %}
</div>
<footer>...页脚...</footer>
</body>
</html>
子模板只需要写:
{% extends "base.html" %}
{% block title %}首页 - 我的网站{% endblock %}
{% block content %}
<h1>欢迎来到首页</h1>
<p>这是内容区域</p>
{% endblock %}
渲染出来,导航栏和页脚自动就有了,你只管填内容。我建议每个项目都搞一个 base.html,哪怕刚开始只有几个页面,后面扩展起来会非常舒服。
{% extends %}必须放在子模板第一行- 父模板用
{% block 名称 %}定义可覆盖区域 - 子模板用同名 block 覆盖内容
- 可以用
{{ block.super }}引用父模板的 block 内容
4.4 静态文件加载:图片、CSS、JS 怎么放
模板里要引用 CSS、JS、图片,总不能写死路径吧?Django 提供了 {% static %} 标签来处理。
首先,在 settings.py 里配置:
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
然后在模板里:
{% load static %}
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<img src="{% static 'images/logo.png' %}" alt="Logo">
注意第一行 {% load static %},这是告诉模板引擎我要用 static 标签。我见过不少新手忘了这行,结果路径死活加载不出来。
collectstatic 命令把所有静态文件收集到一个目录。嗯,这个后面部署章节会细讲。
4.5 自定义过滤器:造个自己的工具
内置过滤器不够用?那就自己写。Django 允许你注册自定义过滤器,用法和内置的一模一样。
步骤很简单:
- 在 app 目录下建一个
templatetags包(必须包含__init__.py) - 在里面写一个 Python 文件,比如
my_filters.py - 注册过滤器
举个例子,我想写一个把字符串变成「首字母大写其余小写」的过滤器:
# myapp/templatetags/my_filters.py
from django import template
register = template.Library()
@register.filter
def capitalize_first(value):
"""将字符串首字母大写,其余小写"""
if not value:
return value
return value[0].upper() + value[1:].lower()
然后在模板里:
{% load my_filters %}
{{ "hello WORLD"|capitalize_first }}
{# 输出:Hello world #}
你还可以写带参数的过滤器:
@register.filter
def multiply(value, arg):
return value * arg
{# 模板中使用:{{ 5|multiply:3 }} 输出 15 #}
int(arg)。
嗯,模板系统这块基本就这些了。你想想看,变量输出、过滤器格式化、继承复用布局、静态文件加载、自定义扩展——这一套组合拳打下来,页面开发效率能翻好几倍。下一章咱们聊聊模型和数据库,那才是 Django 的重头戏。