青少年编程与数学 02-009 Django 5 Web 编程 11课题、模板系统

青少年编程与数学 02-009 Django 5 Web 编程 11课题、模板系统

课题摘要: 本文深入解析了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内容。例如:

    python 复制代码
    from django.shortcuts import render
    
    def 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 %}标签重写相应的内容块.

    html 复制代码
    <!-- base.html -->
    <html>
    <head>
        <title>{% block title %}My Site{% endblock %}</title>
    </head>
    <body>
        {% block content %}
        {% endblock %}
    </body>
    </html>
    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 :用于条件判断.

    html 复制代码
    {% 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 :用于循环遍历可迭代对象,如列表、字典等.

    html 复制代码
    <ul>
    {% for item in items %}
        <li>{{ item.name }}</li>
    {% endfor %}
    </ul>
    • 循环变量 :在for循环中,可以使用一些特殊的变量,如forloop.counter(当前循环的索引,从1开始)、forloop.last(判断是否是最后一个元素)等.
  • with :用于在模板中创建一个临时变量,简化模板的复杂度.

    html 复制代码
    {% with total=items|length %}
        <p>Total items: {{ total }}</p>
    {% endwith %}
模板加载标签
  • extends :用于模板继承,指定当前模板继承的基础模板.

    html 复制代码
    {% extends "base.html" %}
  • block :在继承的模板中定义可以被子模板重写的内容块.

    html 复制代码
    {% block content %}
        <p>This is the default content.</p>
    {% endblock %}
  • include :用于在模板中包含另一个模板片段,可以传递变量.

    html 复制代码
    {% include "header.html" with title="My Page" %}
模板控制标签
  • load :用于加载自定义的模板标签库,使得自定义标签可以在模板中使用.

    html 复制代码
    {% load my_custom_tags %}
  • spaceless :用于移除HTML标签之间的空白字符,减少页面大小.

    html 复制代码
    {% spaceless %}
        <div>
            <p>Hello, World!</p>
        </div>
    {% endspaceless %}
  • autoescape :用于控制自动转义的开启和关闭,防止XSS攻击.

    html 复制代码
    {% autoescape off %}
        <p>{{ user_input }}</p>
    {% endautoescape %}

自定义模板标签

  • 简单标签(Simple Tag) :用于执行一些简单的操作,并返回一个字符串结果.

    python 复制代码
    from django import template
    
    register = template.Library()
    
    @register.simple_tag
    def multiply(x, y):
        return x * y

    在模板中使用:

    html 复制代码
    {% load my_custom_tags %}
    <p>{{ 3|multiply:4 }}</p>
  • 包含标签(Inclusion Tag) :用于渲染一个模板片段,并将结果插入到当前模板中.

    python 复制代码
    @register.inclusion_tag('my_template.html')
    def show_items(items):
        return {'items': items}

    在模板中使用:

    html 复制代码
    {% load my_custom_tags %}
    {% show_items items %}
  • 块标签(Block Tag) :用于创建复杂的模板标签,可以包含其他模板标签和变量.

    python 复制代码
    @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 = nodelist
    
        def render(self, context):
            output = self.nodelist.render(context)
            return '<div>' + output + '</div>'

    在模板中使用:

    html 复制代码
    {% 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内容。

    html 复制代码
    {{ my_html_variable|safe }}
  • escape :对变量进行HTML转义,防止XSS攻击。

    html 复制代码
    {{ user_input|escape }}
  • lower :将字符串转换为小写。

    html 复制代码
    {{ "Hello, World!"|lower }}
  • upper :将字符串转换为大写。

    html 复制代码
    {{ "Hello, World!"|upper }}
  • capitalize :将字符串的首字母大写,其余字母小写。

    html 复制代码
    {{ "hello, world!"|capitalize }}
  • slugify :将字符串转换为URL友好的格式(slug),只包含字母、数字、下划线和连字符。

    html 复制代码
    {{ "Hello, World!"|slugify }}
  • truncatechars :截取字符串,保留指定数量的字符。

    html 复制代码
    {{ "Hello, World!"|truncatechars:5 }}
  • join :将列表中的元素连接成字符串,使用指定的分隔符。

    html 复制代码
    {{ my_list|join:", " }}
日期和时间过滤器
  • date :将日期对象格式化为指定的格式。

    html 复制代码
    {{ my_date|date:"Y-m-d" }}
  • time :将时间对象格式化为指定的格式。

    html 复制代码
    {{ my_time|time:"H:i:s" }}
  • timesince :显示距离指定日期或时间的相对时间。

    html 复制代码
    {{ my_date|timesince }}
  • timeuntil :显示距离指定日期或时间的剩余时间。

    html 复制代码
    {{ my_date|timeuntil }}
列表过滤器
  • first :获取列表的第一个元素。

    html 复制代码
    {{ my_list|first }}
  • last :获取列表的最后一个元素。

    html 复制代码
    {{ my_list|last }}
  • length :获取列表的长度。

    html 复制代码
    {{ my_list|length }}
  • slice :对列表进行切片操作。

    html 复制代码
    {{ my_list|slice:"1:3" }}

自定义过滤器

  • 定义过滤器 :在Django应用的templatetags目录下的Python文件中定义过滤器。首先需要创建一个templatetags目录,并在其中创建一个Python文件(例如my_custom_filters.py),然后编写过滤器代码。

    python 复制代码
    from django import template
    
    register = template.Library()
    
    @register.filter
    def add_prefix(value, prefix):
        return f"{prefix}{value}"
  • 加载过滤器 :在模板中使用{% load %}标签加载自定义过滤器库。

    html 复制代码
    {% load my_custom_filters %}
  • 使用过滤器 :在模板中使用自定义过滤器。

    html 复制代码
    {{ my_variable|add_prefix:"Prefix: " }}

过滤器的注意事项

  • 安全性 :在使用过滤器时,需要注意安全性问题,特别是涉及到HTML内容的过滤器。例如,当使用safe过滤器时,要确保变量的内容是安全的,不会导致XSS攻击.
  • 性能:过滤器的执行会影响模板的渲染性能,尤其是在处理大量数据或复杂逻辑时。应尽量使用内置过滤器,避免过多的自定义过滤器,以提高模板的渲染效率.
  • 可读性:在模板中过度使用过滤器可能导致代码的可读性降低。应合理使用过滤器,保持模板的简洁和清晰.

Django的模板过滤器提供了丰富的功能,使得模板中的变量处理和格式化更加灵活和方便。通过合理使用内置过滤器和自定义过滤器,可以有效地实现模板中的数据展示需求.

四、模板配置

在Django中,模板配置主要通过项目的settings.py文件中的TEMPLATES设置来完成。TEMPLATES是一个列表,其中每个元素都是一个字典,用于配置一个模板引擎。以下是如何进行模板配置的详细步骤和选项:

基本配置

默认情况下,Django已经提供了一个基本的模板配置,通常位于settings.py文件中:

python 复制代码
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列表中的顺序查找模板文件.

  • 示例

    python 复制代码
    'DIRS': [os.path.join(BASE_DIR, 'templates')],

    这里将项目的templates目录添加到模板搜索路径中.

APP_DIRS
  • 作用 :指示Django是否在每个应用的templates子目录中查找模板文件。如果设置为True,Django会在每个应用的templates目录中自动查找模板文件.
  • 默认值True
OPTIONS
  • 作用 :用于配置模板引擎的其他选项。以下是一些常用的选项:
    • context_processors :上下文处理器列表,用于自动添加变量到模板的上下文中。例如,可以添加请求对象、用户对象等.

      python 复制代码
      '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使用文件系统加载器和应用目录加载器.

      python 复制代码
      'OPTIONS': {
          'loaders': [
              'django.template.loaders.filesystem.Loader',
              'django.template.loaders.app_directories.Loader',
          ],
      }
    • debug :模板调试模式,如果设置为True,在模板渲染出错时会显示详细的调试信息.

      python 复制代码
      'OPTIONS': {
          'debug': True,
      }
    • string_if_invalid :无效变量的默认值,用于在模板中访问不存在的变量时返回一个指定的字符串.

      python 复制代码
      'OPTIONS': {
          'string_if_invalid': 'Invalid Variable',
      }

多模板引擎配置

如果需要在同一个项目中使用多个模板引擎,可以在TEMPLATES列表中添加多个配置字典。例如,同时使用Django模板和Jinja2模板:

python 复制代码
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.py
    myblog/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    blog/
        __init__.py
        admin.py
        apps.py
        models.py
        tests.py
        urls.py
        views.py
        templates/
            blog/
                base.html
                index.html
                detail.html

创建项目和应用

  1. 创建Django项目:

    bash 复制代码
    django-admin startproject myblog
  2. 进入项目目录:

    bash 复制代码
    cd myblog
  3. 创建应用:

    bash 复制代码
    python manage.py startapp blog

配置项目

  1. myblog/settings.py中添加应用到INSTALLED_APPS

    python 复制代码
    INSTALLED_APPS = [
        # ...
        'blog',
    ]
  2. myblog/urls.py中包含应用的URL配置:

    python 复制代码
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('blog/', include('blog.urls')),
    ]

创建模型

blog/models.py中定义文章模型:

python 复制代码
from django.db import models

class 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

运行迁移命令创建数据库表:

bash 复制代码
python manage.py makemigrations
python manage.py migrate

创建视图

blog/views.py中定义视图函数:

python 复制代码
from django.shortcuts import render, get_object_or_404
from .models import Post

def 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(基础模板):

    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>&copy; 2024 My Blog</p>
        </footer>
    </body>
    </html>
  • index.html(文章列表页面):

    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(文章详情页面):

    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:

python 复制代码
from django.urls import path
from . import views

app_name = 'blog'

urlpatterns = [
    path('', views.index, name='index'),
    path('<int:post_id>/', views.detail, name='detail'),
]

运行项目

  1. 创建超级用户:

    bash 复制代码
    python manage.py createsuperuser
  2. 运行开发服务器:

    bash 复制代码
    python manage.py runserver
  3. 访问http://127.0.0.1:8000/blog/查看文章列表页面,访问http://127.0.0.1:8000/blog/1/查看文章详情页面(需要先在后台创建文章).

这个示例项目展示了如何使用Django的模板系统创建一个简单的博客应用,包括基础模板、列表页面和详情页面的模板配置和使用.

相关推荐
Aerkui8 分钟前
Python标准库-copy
开发语言·python
Try,多训练41 分钟前
Pytorch查看神经网络结构和参数量
人工智能·pytorch·python
hweiyu002 小时前
Python从入门到精通全套视频教程免费
开发语言·python
安迪小宝4 小时前
python基础语法10-异常处理
服务器·开发语言·python
Kylin5244 小时前
Java实验二
java·开发语言·python
深度学习lover4 小时前
<数据集>苹果识别数据集<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·苹果识别
ldq_sd5 小时前
Django 创建CSV文件
服务器·django
DreamNotOver6 小时前
自动提取pdf公式 ➕ 输出 LaTeX
python·pdf·gui·提取公式
嗨信奥6 小时前
2025年3月GESP C++四级等级考试真题——二阶矩阵
c++·青少年编程
Jacky-0087 小时前
python reportlab模块----操作PDF文件
python