Django 模板

以下是用中文详细讲解 Django 模板(Templates)的指南,涵盖模板的作用、创建方法、常用语法、配置方式以及最佳实践。我会保持简洁清晰,适合初学者和进阶用户,并提供实用示例。如果你有特定问题或需要更深入的内容,请随时告知!


什么是 Django 模板?

Django 模板是用于生成动态 HTML 页面的文件,通常是 HTML 文件,结合 Django 模板语言(DTL, Django Template Language)来嵌入动态内容。模板分离了前端展示与后端逻辑,遵循 Django 的 MTV(模型-模板-视图)架构。

  • 作用:渲染动态数据(如数据库查询结果、用户输入)到 HTML 页面。
  • 特点
  • 简单易学,支持变量、循环、条件等。
  • 支持模板继承和块重用,方便页面复用。
  • 内置安全机制(如自动转义 HTML)。

1. 配置模板

在 Django 项目中,模板需要正确配置才能被视图使用。

配置 settings.py

确保 settings.pyTEMPLATES 设置正确,默认配置如下:

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.pyDIRS 中配置。

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、图片)需配合模板使用。

  1. 配置静态文件
    settings.py 中:
   STATIC_URL = '/static/'
   STATICFILES_DIRS = [BASE_DIR / 'static']
   STATIC_ROOT = BASE_DIR / 'staticfiles'  # 生产环境收集目录
  1. 目录结构
   static/
   └── myapp/
       ├── css/
       │   └── style.css
       └── images/
           └── logo.png
  1. 在模板中使用
   {% load static %}
   <link rel="stylesheet" href="{% static 'myapp/css/style.css' %}">
   <img src="{% static 'myapp/images/logo.png' %}" alt="Logo">
  1. 生产环境
    运行 python manage.py collectstatic 将静态文件收集到 STATIC_ROOT

5. 最佳实践

  1. 模板组织
  • 按应用隔离模板(如 templates/myapp/)。
  • 使用全局 base.html 作为父模板,减少重复代码。
  1. 命名清晰
  • 模板文件使用描述性名称(如 home.htmluser_profile.html)。
  • 块名(block)应直观(如 contentsidebar)。
  1. 安全注意
  • DTL 默认自动转义 HTML(防止 XSS 攻击)。若需渲染 HTML,使用 {{ content | safe }}{% autoescape off %},但要确保内容安全。
  • 示例:
    html {{ content | safe }}
  1. 复用与模块化
  • 使用 {% include %}{% extends %} 提高代码复用率。
  • 提取通用组件(如导航、表单)到单独模板。
  1. 性能优化
  • 避免在模板中写复杂逻辑,逻辑应放在视图或模型中。
  • 使用缓存({% cache %})减少重复渲染:
    html {% load cache %} {% cache 500 sidebar request.user.username %} <!-- 缓存内容 --> {% endcache %}

6. 常见问题

  1. 模板未找到
  • 检查 settings.py 中的 TEMPLATES 配置,确保 APP_DIRS: TrueDIRS 包含模板路径。
  • 确认模板文件路径(如 myapp/templates/myapp/home.html)。
  1. 变量未显示
  • 确保视图传递了正确的上下文变量。
  • 检查变量名是否拼写正确。
  1. 静态文件未加载
  • 运行 python manage.py collectstatic(生产环境)。
  • 确保 {% load static %} 已添加。
  1. 继承问题
  • 确认子模板的 {% 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、组织模板目录、遵循最佳实践,可以构建高效、可维护的前端页面。

如果你需要更复杂的模板示例(如表单渲染、分页)、特定标签的深入讲解,或调试模板问题的方法,请告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注