青少年编程与数学 02-009 Django 5 Web 编程 11课题、模板系统
- 一、模板
- 1. 模板的基本概念
- 2. 模板的加载和渲染
- 3. 模板继承
- 4. 自定义模板标签和过滤器
- 5. 模板的配置和优化
- 二、模板标签
- 基本用法
- 常用模板标签
- 控制流标签
- 模板加载标签
- 模板控制标签
- 自定义模板标签
- 三、模板过滤器
- 基本用法
- 内置过滤器
- 字符串过滤器
- 日期和时间过滤器
- 列表过滤器
- 自定义过滤器
- 过滤器的注意事项
- 四、模板配置
- 基本配置
- 配置选项详解
- `BACKEND`
- `DIRS`
- `APP_DIRS`
- `OPTIONS`
- 多模板引擎配置
- 五、练习
- 项目结构
- 创建项目和应用
- 配置项目
- 创建模型
- 创建视图
- 创建模板
- 配置应用的URL
- 运行项目
课题摘要: 本文深入解析了Django的模板系统,涵盖模板的基本概念、加载与渲染、继承、自定义标签和过滤器,以及模板配置。模板是包含静态和动态内容的文本文件,通过标签和变量实现动态插入。上下文是传递给模板的数据字典,而模板标签和过滤器分别用于控制逻辑和格式化变量。文章介绍了如何通过
render()
函数结合模板和上下文生成HTML内容,以及如何利用模板继承和块标签简化页面结构。此外,还讲解了自定义模板标签和过滤器的创建方法,以及如何在settings.py
中配置模板引擎的选项,如模板目录和调试模式。最后,通过一个博客应用示例,展示了模板系统的实际应用,包括基础模板、列表页面和详情页面的创建和配置。
一、模板
Django的模板系统是一个强大的工具,用于将数据动态地插入到HTML页面中。它允许开发者将业务逻辑与展示逻辑分离,使得前端页面的开发更加灵活和高效。以下是Django模板系统的详细解析:
1. 模板的基本概念
- 模板 (Template):一个文本文件,通常是一个HTML文件,包含用于展示的静态内容和动态内容的占位符。动态内容通过模板标签和变量来实现.
- 上下文 (Context):一个字典,包含了模板中需要使用的变量和数据。在视图中创建上下文,并将其传递给模板进行渲染.
- 模板标签 (Template Tags):用于在模板中插入动态内容或控制模板的逻辑流程。例如,
{% for %}
用于循环,{% if %}
用于条件判断. - 模板过滤器 (Template Filters):用于对变量的值进行格式化或处理。例如,
|upper
将变量的值转换为大写,|date:"Y-m-d"
将日期格式化为指定格式.
2. 模板的加载和渲染
- 加载模板:Django通过模板加载器来加载模板文件。默认情况下,Django会从
settings.py
文件中配置的TEMPLATES
设置的DIRS
选项指定的目录中查找模板文件. - 渲染模板:在视图中,使用
render()
函数将模板和上下文结合起来,生成最终的HTML内容。例如:
在这个例子中,from django.shortcuts import renderdef my_view(request):context = {'message': 'Hello, Django!'}return render(request, 'my_template.html', context)
my_template.html
是模板文件,context
是上下文字典,render()
函数将上下文中的变量message
插入到模板中,生成最终的HTML页面.
3. 模板继承
- 模板继承:Django模板系统支持模板继承,允许创建一个基础模板,其他模板可以继承它并重写其中的部分内容。基础模板通常包含页面的公共结构,如头部、尾部、导航栏等.
- 块标签 (block tag):在基础模板中,使用
{% block %}
标签定义可以被子模板重写的内容块。子模板通过{% extends %}
标签继承基础模板,并使用{% block %}
标签重写相应的内容块.<!-- base.html --> <html> <head><title>{% block title %}My Site{% endblock %}</title> </head> <body>{% block content %}{% endblock %} </body> </html>
<!-- child.html --> {% extends "base.html" %}{% block title %}Child Page{% endblock %}{% block content %} <p>This is the content of the child page.</p> {% endblock %}
4. 自定义模板标签和过滤器
- 自定义模板标签:可以通过编写Python代码来创建自定义的模板标签,实现特定的功能。自定义标签可以是简单的标签,也可以是包含块的标签.
- 自定义模板过滤器:可以编写自定义的过滤器来对变量的值进行处理。自定义过滤器需要在Python代码中定义,并在模板中注册后才能使用.
5. 模板的配置和优化
- 模板配置:在
settings.py
文件中,可以通过TEMPLATES
设置来配置模板引擎的选项,如模板目录、模板后缀、模板缓存等. - 模板缓存:为了提高性能,可以开启模板缓存功能,使得模板文件在第一次加载后被缓存起来,后续请求可以直接使用缓存的模板,减少文件读取和解析的时间.
Django的模板系统提供了丰富的功能和灵活的扩展性,使得开发者能够高效地开发出动态的Web页面,同时保持代码的清晰和可维护性.
二、模板标签
Django的模板标签(Template Tags)是模板系统中用于插入动态内容和控制模板逻辑的工具。模板标签可以执行各种操作,如循环、条件判断、加载模板片段等。以下是对Django模板标签的详细解析:
基本用法
- 语法:模板标签使用花括号和百分号包围,例如
{% tag %}
. - 位置:模板标签通常放在HTML代码中需要动态插入内容或控制逻辑的地方.
常用模板标签
控制流标签
- if/elif/else:用于条件判断.
{% if user.is_authenticated %}<p>Welcome, {{ user.username }}!</p> {% elif user.is_anonymous %}<p>Please log in.</p> {% else %}<p>Unknown user status.</p> {% endif %}
- for:用于循环遍历可迭代对象,如列表、字典等.
<ul> {% for item in items %}<li>{{ item.name }}</li> {% endfor %} </ul>
- 循环变量:在
for
循环中,可以使用一些特殊的变量,如forloop.counter
(当前循环的索引,从1开始)、forloop.last
(判断是否是最后一个元素)等.
- 循环变量:在
- with:用于在模板中创建一个临时变量,简化模板的复杂度.
{% with total=items|length %}<p>Total items: {{ total }}</p> {% endwith %}
模板加载标签
- extends:用于模板继承,指定当前模板继承的基础模板.
{% extends "base.html" %}
- block:在继承的模板中定义可以被子模板重写的内容块.
{% block content %}<p>This is the default content.</p> {% endblock %}
- include:用于在模板中包含另一个模板片段,可以传递变量.
{% include "header.html" with title="My Page" %}
模板控制标签
- load:用于加载自定义的模板标签库,使得自定义标签可以在模板中使用.
{% load my_custom_tags %}
- spaceless:用于移除HTML标签之间的空白字符,减少页面大小.
{% spaceless %}<div><p>Hello, World!</p></div> {% endspaceless %}
- autoescape:用于控制自动转义的开启和关闭,防止XSS攻击.
{% autoescape off %}<p>{{ user_input }}</p> {% endautoescape %}
自定义模板标签
- 简单标签(Simple Tag):用于执行一些简单的操作,并返回一个字符串结果.
在模板中使用:from django import templateregister = template.Library()@register.simple_tag def multiply(x, y):return x * y
{% load my_custom_tags %} <p>{{ 3|multiply:4 }}</p>
- 包含标签(Inclusion Tag):用于渲染一个模板片段,并将结果插入到当前模板中.
在模板中使用:@register.inclusion_tag('my_template.html') def show_items(items):return {'items': items}
{% load my_custom_tags %} {% show_items items %}
- 块标签(Block Tag):用于创建复杂的模板标签,可以包含其他模板标签和变量.
在模板中使用:@register.tag(name='my_block_tag') def do_my_block_tag(parser, token):nodelist = parser.parse(('end_my_block_tag',))parser.delete_first_token()return MyBlockNode(nodelist)class MyBlockNode(template.Node):def __init__(self, nodelist):self.nodelist = nodelistdef render(self, context):output = self.nodelist.render(context)return '<div>' + output + '</div>'
{% load my_custom_tags %} {% my_block_tag %}<p>Hello, World!</p> {% end_my_block_tag %}
Django的模板标签提供了丰富的功能,使得模板的开发更加灵活和高效。通过合理使用模板标签,可以有效地控制模板的逻辑和结构,实现动态内容的展示.
三、模板过滤器
Django的模板过滤器(Template Filters)是用于对模板中的变量值进行处理和格式化的工具。过滤器可以对变量进行各种操作,如字符串处理、日期格式化、列表操作等。以下是对Django模板过滤器的详细解析:
基本用法
- 语法:过滤器使用管道符号(
|
)连接变量和过滤器名称,例如{{ variable|filter }}
。 - 链式使用:可以将多个过滤器串联使用,对变量进行多重处理,例如
{{ variable|filter1|filter2 }}
。
内置过滤器
Django提供了许多内置的过滤器,以下是一些常用的内置过滤器:
字符串过滤器
safe
:标记变量为安全的,不会自动转义HTML内容。{{ my_html_variable|safe }}
escape
:对变量进行HTML转义,防止XSS攻击。{{ user_input|escape }}
lower
:将字符串转换为小写。{{ "Hello, World!"|lower }}
upper
:将字符串转换为大写。{{ "Hello, World!"|upper }}
capitalize
:将字符串的首字母大写,其余字母小写。{{ "hello, world!"|capitalize }}
slugify
:将字符串转换为URL友好的格式(slug),只包含字母、数字、下划线和连字符。{{ "Hello, World!"|slugify }}
truncatechars
:截取字符串,保留指定数量的字符。{{ "Hello, World!"|truncatechars:5 }}
join
:将列表中的元素连接成字符串,使用指定的分隔符。{{ my_list|join:", " }}
日期和时间过滤器
date
:将日期对象格式化为指定的格式。{{ my_date|date:"Y-m-d" }}
time
:将时间对象格式化为指定的格式。{{ my_time|time:"H:i:s" }}
timesince
:显示距离指定日期或时间的相对时间。{{ my_date|timesince }}
timeuntil
:显示距离指定日期或时间的剩余时间。{{ my_date|timeuntil }}
列表过滤器
first
:获取列表的第一个元素。{{ my_list|first }}
last
:获取列表的最后一个元素。{{ my_list|last }}
length
:获取列表的长度。{{ my_list|length }}
slice
:对列表进行切片操作。{{ my_list|slice:"1:3" }}
自定义过滤器
- 定义过滤器:在Django应用的
templatetags
目录下的Python文件中定义过滤器。首先需要创建一个templatetags
目录,并在其中创建一个Python文件(例如my_custom_filters.py
),然后编写过滤器代码。from django import templateregister = template.Library()@register.filter def add_prefix(value, prefix):return f"{prefix}{value}"
- 加载过滤器:在模板中使用
{% load %}
标签加载自定义过滤器库。{% load my_custom_filters %}
- 使用过滤器:在模板中使用自定义过滤器。
{{ my_variable|add_prefix:"Prefix: " }}
过滤器的注意事项
- 安全性:在使用过滤器时,需要注意安全性问题,特别是涉及到HTML内容的过滤器。例如,当使用
safe
过滤器时,要确保变量的内容是安全的,不会导致XSS攻击. - 性能:过滤器的执行会影响模板的渲染性能,尤其是在处理大量数据或复杂逻辑时。应尽量使用内置过滤器,避免过多的自定义过滤器,以提高模板的渲染效率.
- 可读性:在模板中过度使用过滤器可能导致代码的可读性降低。应合理使用过滤器,保持模板的简洁和清晰.
Django的模板过滤器提供了丰富的功能,使得模板中的变量处理和格式化更加灵活和方便。通过合理使用内置过滤器和自定义过滤器,可以有效地实现模板中的数据展示需求.
四、模板配置
在Django中,模板配置主要通过项目的settings.py
文件中的TEMPLATES
设置来完成。TEMPLATES
是一个列表,其中每个元素都是一个字典,用于配置一个模板引擎。以下是如何进行模板配置的详细步骤和选项:
基本配置
默认情况下,Django已经提供了一个基本的模板配置,通常位于settings.py
文件中:
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [],'APP_DIRS': True,'OPTIONS': {# Some options here},},
]
配置选项详解
BACKEND
- 作用:指定模板引擎的后端。Django默认使用
django.template.backends.django.DjangoTemplates
,这是Django自带的模板引擎. - 可选值:除了默认的Django模板引擎,还可以使用其他模板引擎,如Jinja2等.
DIRS
- 作用:指定模板文件的搜索目录。Django会按照
DIRS
列表中的顺序查找模板文件. - 示例:
这里将项目的'DIRS': [os.path.join(BASE_DIR, 'templates')],
templates
目录添加到模板搜索路径中.
APP_DIRS
- 作用:指示Django是否在每个应用的
templates
子目录中查找模板文件。如果设置为True
,Django会在每个应用的templates
目录中自动查找模板文件. - 默认值:
True
OPTIONS
- 作用:用于配置模板引擎的其他选项。以下是一些常用的选项:
context_processors
:上下文处理器列表,用于自动添加变量到模板的上下文中。例如,可以添加请求对象、用户对象等.'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',], }
loaders
:模板加载器列表,用于指定如何加载模板文件。默认情况下,Django使用文件系统加载器和应用目录加载器.'OPTIONS': {'loaders': ['django.template.loaders.filesystem.Loader','django.template.loaders.app_directories.Loader',], }
debug
:模板调试模式,如果设置为True
,在模板渲染出错时会显示详细的调试信息.'OPTIONS': {'debug': True, }
string_if_invalid
:无效变量的默认值,用于在模板中访问不存在的变量时返回一个指定的字符串.'OPTIONS': {'string_if_invalid': 'Invalid Variable', }
多模板引擎配置
如果需要在同一个项目中使用多个模板引擎,可以在TEMPLATES
列表中添加多个配置字典。例如,同时使用Django模板和Jinja2模板:
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [os.path.join(BASE_DIR, 'django_templates')],'APP_DIRS': True,'OPTIONS': {# Django template options},},{'BACKEND': 'django.template.backends.jinja2.Jinja2','DIRS': [os.path.join(BASE_DIR, 'jinja2_templates')],'APP_DIRS': False,'OPTIONS': {'environment': 'myapp.jinja2.environment',},},
]
在这个示例中,Django模板和Jinja2模板分别配置了不同的模板目录和选项.
通过合理配置TEMPLATES
设置,可以满足不同项目的需求,实现高效的模板管理和渲染.
五、练习
以下是一个简单的Django应用模板示例项目,该项目包含一个简单的博客应用,具有文章列表和文章详情页面的功能:
项目结构
myblog/manage.pymyblog/__init__.pysettings.pyurls.pywsgi.pyblog/__init__.pyadmin.pyapps.pymodels.pytests.pyurls.pyviews.pytemplates/blog/base.htmlindex.htmldetail.html
创建项目和应用
- 创建Django项目:
django-admin startproject myblog
- 进入项目目录:
cd myblog
- 创建应用:
python manage.py startapp blog
配置项目
- 在
myblog/settings.py
中添加应用到INSTALLED_APPS
:INSTALLED_APPS = [# ...'blog', ]
- 在
myblog/urls.py
中包含应用的URL配置:from django.contrib import admin from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('blog/', include('blog.urls')), ]
创建模型
在blog/models.py
中定义文章模型:
from django.db import modelsclass Post(models.Model):title = models.CharField(max_length=200)content = models.TextField()created_at = models.DateTimeField(auto_now_add=True)def __str__(self):return self.title
运行迁移命令创建数据库表:
python manage.py makemigrations
python manage.py migrate
创建视图
在blog/views.py
中定义视图函数:
from django.shortcuts import render, get_object_or_404
from .models import Postdef index(request):posts = Post.objects.all()return render(request, 'blog/index.html', {'posts': posts})def detail(request, post_id):post = get_object_or_404(Post, pk=post_id)return render(request, 'blog/detail.html', {'post': post})
创建模板
在blog/templates/blog/
目录下创建模板文件:
-
base.html
(基础模板):<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>{% block title %}My Blog{% endblock %}</title> </head> <body><header><h1>My Blog</h1></header><main>{% block content %}{% endblock %}</main><footer><p>© 2024 My Blog</p></footer> </body> </html>
-
index.html
(文章列表页面):{% extends "blog/base.html" %}{% block title %}Blog Posts{% endblock %}{% block content %} <h2>Blog Posts</h2> <ul>{% for post in posts %}<li><a href="{% url 'blog:detail' post.id %}">{{ post.title }}</a><small>Published on {{ post.created_at|date:"Y-m-d" }}</small></li>{% endfor %} </ul> {% endblock %}
-
detail.html
(文章详情页面):{% extends "blog/base.html" %}{% block title %}{{ post.title }}{% endblock %}{% block content %} <h2>{{ post.title }}</h2> <p>{{ post.content }}</p> <p>Published on {{ post.created_at|date:"Y-m-d" }}</p> <a href="{% url 'blog:index' %}">Back to posts</a> {% endblock %}
配置应用的URL
在blog/urls.py
中定义应用的URL:
from django.urls import path
from . import viewsapp_name = 'blog'urlpatterns = [path('', views.index, name='index'),path('<int:post_id>/', views.detail, name='detail'),
]
运行项目
- 创建超级用户:
python manage.py createsuperuser
- 运行开发服务器:
python manage.py runserver
- 访问
http://127.0.0.1:8000/blog/
查看文章列表页面,访问http://127.0.0.1:8000/blog/1/
查看文章详情页面(需要先在后台创建文章).
这个示例项目展示了如何使用Django的模板系统创建一个简单的博客应用,包括基础模板、列表页面和详情页面的模板配置和使用.