Django 模板
以下是用中文详细讲解 Django 模板(Templates)的指南,涵盖模板的作用、创建方法、常用语法、配置方式以及最佳实践。我会保持简洁清晰,适合初学者和进阶用户,并提供实用示例。如果你有特定问题或需要更深入的内容,请随时告知!
什么是 Django 模板?
Django 模板是用于生成动态 HTML 页面的文件,通常是 HTML 文件,结合 Django 模板语言(DTL, Django Template Language)来嵌入动态内容。模板分离了前端展示与后端逻辑,遵循 Django 的 MTV(模型-模板-视图)架构。
- 作用:渲染动态数据(如数据库查询结果、用户输入)到 HTML 页面。
- 特点:
- 简单易学,支持变量、循环、条件等。
- 支持模板继承和块重用,方便页面复用。
- 内置安全机制(如自动转义 HTML)。
1. 配置模板
在 Django 项目中,模板需要正确配置才能被视图使用。
配置 settings.py
确保 settings.py
中 TEMPLATES
设置正确,默认配置如下:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # 全局模板目录(可选)
'APP_DIRS': True, # 自动查找每个应用下的 templates 文件夹
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
- 关键点:
'DIRS'
:指定全局模板目录(如project/templates/
),用于存放跨应用的模板。'APP_DIRS': True
:允许 Django 自动查找每个应用下的templates/
文件夹。context_processors
:为模板提供全局上下文变量(如用户认证信息)。
模板目录结构
推荐按应用组织模板:
myproject/
├── myapp/
│ └── templates/
│ └── myapp/
│ └── home.html
└── templates/
└── base.html # 全局模板
- 约定:应用内模板放在
templates/myapp/
子目录中,避免命名冲突。 - 全局模板:放在
project/templates/
,在settings.py
的DIRS
中配置。
2. 创建模板
假设我们要创建一个简单的首页模板 home.html
。
示例:myapp/templates/myapp/home.html
<!DOCTYPE html>
<html>
<head>
<title>我的 Django 页面</title>
</head>
<body>
<h1>欢迎,{{ user_name }}!</h1>
<p>这是我的第一个 Django 模板!</p>
</body>
</html>
渲染模板
在 myapp/views.py
中编写视图,使用 render
函数渲染模板:
from django.shortcuts import render
def home(request):
return render(request, 'myapp/home.html', {'user_name': '访客'})
- 说明:
render(request, template_name, context)
:将模板与上下文数据结合,生成最终 HTML。'user_name'
是上下文变量,模板中使用{{ user_name }}
访问。
配置 URL
在 myapp/urls.py
中映射视图:
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
]
确保项目 urls.py
包含应用路由:
from django.urls import path, include
urlpatterns = [
path('', include('myapp.urls')),
]
运行服务器(python manage.py runserver
),访问 http://127.0.0.1:8000/
,即可看到渲染后的页面。
3. Django 模板语言(DTL)
DTL 是 Django 的内置模板语言,支持变量、过滤器、标签等。
3.1 变量
- 语法:
{{ variable_name }}
- 作用:显示视图传递的上下文变量。
- 示例:
<p>用户名:{{ user_name }}</p>
- 访问对象属性:使用点号(
.
)访问字典、对象或列表:
<p>用户邮箱:{{ user.email }}</p>
<p>列表第一项:{{ my_list.0 }}</p>
3.2 过滤器
- 语法:
{{ variable | filter }}
- 作用:对变量进行格式化或转换。
- 常用过滤器:
{{ value | lower }}
:转换为小写。{{ value | date:"Y-m-d" }}
:格式化日期。{{ value | default:"无数据" }}
:如果变量为空,显示默认值。{{ value | truncatewords:10 }}
:截断到 10 个单词。- 示例:
<p>用户名(小写):{{ user_name | lower }}</p>
<p>创建时间:{{ created_at | date:"Y-m-d H:i" }}</p>
3.3 标签
- 语法:
{% tag %}
- 作用:实现逻辑控制,如循环、条件判断。
- 常用标签:
- 条件:
{% if %}
、{% else %}
、{% endif %}
html {% if user.is_authenticated %} <p>欢迎,{{ user.username }}!</p> {% else %} <p>请登录!</p> {% endif %}
- 循环:
{% for %}
、{% endfor %}
html ¨K44K
- URL 反向解析:
{% url 'name' arg1 arg2 %}
html <a href="{% url 'home' %}">返回首页</a>
- 加载静态文件:
{% load static %}
html {% load static %} <img src="{% static 'myapp/images/logo.png' %}" alt="Logo">
3.4 模板继承
- 作用:通过继承复用通用页面结构(如导航栏、页脚)。
- 父模板(
templates/base.html
):
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}默认标题{% endblock %}</title>
{% load static %}
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
<header>通用导航栏</header>
{% block content %}
{% endblock %}
<footer>通用页脚</footer>
</body>
</html>
- 子模板(
myapp/templates/myapp/home.html
):
{% extends 'base.html' %}
{% block title %}首页{% endblock %}
{% block content %}
<h1>欢迎,{{ user_name }}!</h1>
<p>这是首页内容。</p>
{% endblock %}
- 说明:
{% extends 'base.html' %}
:继承父模板。{% block %}
:定义可被子模板覆盖的内容块。
3.5 包含模板
- 作用:将通用模块(如导航栏)提取为独立模板,复用在多处。
- 示例(
templates/nav.html
):
<nav>
<a href="{% url 'home' %}">首页</a>
<a href="{% url 'about' %}">关于</a>
</nav>
- 使用:
{% include 'nav.html' %}
4. 加载静态文件
静态文件(如 CSS、JS、图片)需配合模板使用。
- 配置静态文件:
在settings.py
中:
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
STATIC_ROOT = BASE_DIR / 'staticfiles' # 生产环境收集目录
- 目录结构:
static/
└── myapp/
├── css/
│ └── style.css
└── images/
└── logo.png
- 在模板中使用:
{% load static %}
<link rel="stylesheet" href="{% static 'myapp/css/style.css' %}">
<img src="{% static 'myapp/images/logo.png' %}" alt="Logo">
- 生产环境:
运行python manage.py collectstatic
将静态文件收集到STATIC_ROOT
。
5. 最佳实践
- 模板组织:
- 按应用隔离模板(如
templates/myapp/
)。 - 使用全局
base.html
作为父模板,减少重复代码。
- 命名清晰:
- 模板文件使用描述性名称(如
home.html
、user_profile.html
)。 - 块名(
block
)应直观(如content
、sidebar
)。
- 安全注意:
- DTL 默认自动转义 HTML(防止 XSS 攻击)。若需渲染 HTML,使用
{{ content | safe }}
或{% autoescape off %}
,但要确保内容安全。 - 示例:
html {{ content | safe }}
- 复用与模块化:
- 使用
{% include %}
和{% extends %}
提高代码复用率。 - 提取通用组件(如导航、表单)到单独模板。
- 性能优化:
- 避免在模板中写复杂逻辑,逻辑应放在视图或模型中。
- 使用缓存(
{% cache %}
)减少重复渲染:html {% load cache %} {% cache 500 sidebar request.user.username %} <!-- 缓存内容 --> {% endcache %}
6. 常见问题
- 模板未找到:
- 检查
settings.py
中的TEMPLATES
配置,确保APP_DIRS: True
或DIRS
包含模板路径。 - 确认模板文件路径(如
myapp/templates/myapp/home.html
)。
- 变量未显示:
- 确保视图传递了正确的上下文变量。
- 检查变量名是否拼写正确。
- 静态文件未加载:
- 运行
python manage.py collectstatic
(生产环境)。 - 确保
{% load static %}
已添加。
- 继承问题:
- 确认子模板的
{% extends %}
路径正确。 - 检查块名是否匹配。
7. 示例:完整模板系统
父模板(templates/base.html
)
<!DOCTYPE html>
<html>
<head>
{% load static %}
<title>{% block title %}我的网站{% endblock %}</title>
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
<header>
{% include 'nav.html' %}
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>© 2025 我的网站</footer>
</body>
</html>
子模板(myapp/templates/myapp/home.html
)
{% extends 'base.html' %}
{% block title %}首页{% endblock %}
{% block content %}
<h1>欢迎,{{ user_name }}!</h1>
<ul>
{% for item in items %}
<li>{{ item.name }} - {{ item.description | truncatewords:10 }}</li>
{% empty %}
<li>暂无数据</li>
{% endfor %}
</ul>
{% endblock %}
视图(myapp/views.py
)
from django.shortcuts import render
from .models import Item
def home(request):
items = Item.objects.all()
return render(request, 'myapp/home.html', {
'user_name': request.user.username or '访客',
'items': items,
})
模型(myapp/models.py
)
from django.db import models
class Item(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
def __str__(self):
return self.name
总结
Django 模板通过 DTL 提供强大的动态渲染能力,支持变量、过滤器、标签、继承和静态文件加载。合理配置 settings.py
、组织模板目录、遵循最佳实践,可以构建高效、可维护的前端页面。
如果你需要更复杂的模板示例(如表单渲染、分页)、特定标签的深入讲解,或调试模板问题的方法,请告诉我!