青少年编程与数学 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的模板系统创建一个简单的博客应用,包括基础模板、列表页面和详情页面的模板配置和使用.

相关推荐
沃洛德.辛肯31 分钟前
PyTorch 的 F.scaled_dot_product_attention 返回Nan
人工智能·pytorch·python
noravinsc43 分钟前
人大金仓数据库 与django结合
数据库·python·django
豌豆花下猫1 小时前
Python 潮流周刊#102:微软裁员 Faster CPython 团队(摘要)
后端·python·ai
yzx9910131 小时前
Gensim 是一个专为 Python 设计的开源库
开发语言·python·开源
麻雀无能为力2 小时前
python自学笔记2 数据类型
开发语言·笔记·python
Ndmzi2 小时前
matlab与python问题解析
python·matlab
懒大王爱吃狼2 小时前
怎么使用python进行PostgreSQL 数据库连接?
数据库·python·postgresql
猫猫村晨总2 小时前
网络爬虫学习之httpx的使用
爬虫·python·httpx
web150854159352 小时前
Python线性回归:从理论到实践的完整指南
python·机器学习·线性回归
ayiya_Oese2 小时前
[训练和优化] 3. 模型优化
人工智能·python·深度学习·神经网络·机器学习