1 简述
作为一个web框架,django需要一种方便的模式动态生成html,常见方式是依靠django已有的html模板, 模板:包含了html输出的静态部分,以及对应的特殊语法,描述了如何动态插入内容。 一个django项目可以配置多个末班引擎,django提供了后端,为jinja2(python流行的模板引擎)和自带的模板语言(DTL) DTL:DjangoTemplates
2 django模板语言
以下是概述,详情参考:https://docs.djangoproject.com/zh-hans/4.0/ref/templates/language/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My test page</title>
</head>
<body>
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
<fieldset>
<legend><h1>{{ question.question_text }}</h1></legend>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
</fieldset>
<input type="submit" value="Vote">
</form>
</body>
</html>
2.1 语法
django模板是啥?是一个文本文档或Python字符串,用 Django 模板语言标记的,其中模板引擎主要用来识别变量、标签
2.1.1 变量
变量从上下文中输出一个值,上下文类似字典,将键映射到值,变量被 {{ }} 保住。现在有个上下文, {'first_name': 'John', 'last_name': 'Doe'} ,html中编写如下:
My first name is {{ first_name }}. My last name is {{ last_name }}.
2.1.2 标签
标签在渲染过程中提供了任意逻辑,标签可以输出内容,或用作控制结构如 “if” 语句和 “for” 循环,或从数据库中抓取内容,甚至可以访问其他模板标签。 例如:
{% csrf_token %} > 这个标签用于 CSRF 保护{% if user.is_authenticated %}Hello, {{ user.username }}.{% endif %} > 这个用于条件判断- autoescape:控制当前的自动转义行为。该标签以 on 或 off 作为参数,决定块内是否有自动转义行为。
{% autoescape on %}
{{ body }}
{% endautoescape %}
- block:定义一个可以被子模板覆盖的块
- comment:忽略 {% comment %} 和 {% endcomment %} 之间的所有内容。可以在第一个标签中插入一个可选的注释。不能被嵌套
<p>Rendered text with {{ pub_date|date:"c" }}</p>
{% comment "Optional note" %}
<p>Commented out text with {{ create_date|date:"c" }}</p>
{% endcomment %}
- cycle:每次遇到这个标记时,都会产生一个参数。代码执行到 class 的时候会自动取值,第一次取值 rowvalue1 ,第二次 rowvalue2,第三次 又是1,开始循环
# 交替使用变量的值
{% for o in some_list %}
<tr class="{% cycle rowvalue1 rowvalue2 %}">
...
</tr>
{% endfor %}
# 混合变量和字符串
{% for o in some_list %}
<tr class="{% cycle 'row1' rowvalue2 'row3' %}">
...
</tr>
{% endfor %}
# 在循环中的变量将被转义
{% for o in some_list %}
<tr class="{% autoescape off %}{% cycle rowvalue1 rowvalue2 %}{% endautoescape %}">
...
</tr>
{% endfor %}
# 引用一个周期的当前值,而不是前进到下一个值
{% cycle 'row1' 'row2' as rowcolors %}
- debug:输出大量调试信息,包括当前上下文和导入的模块
- extends:该模板扩展了一个父模板
{% extends "base.html" %} (作为父带引号)使用字面值"base.html"要扩展的模板的名称。
{% extends "./base2.html" %}
{% extends "../base1.html" %}
{% extends "./my/base3.html" %}
- 其他标签: filter、firstof、for、for… empty、if等。
内置标签详情,参考:https://docs.djangoproject.com/zh-hans/4.0/ref/templates/builtins/#ref-templates-builtins-tags
2.1.3 过滤器
过滤器转换变量和标签参数的值
- title
上下文 {'django': 'the web framework for perfectionists with deadlines'} ,过滤器处理 {{ django|title }} ,输出:The Web Framework For Perfectionists With Deadlines - date
{{ my_date|date:"Y-m-d" }} - add
{{ value|add:"2" }} ,如果value的值4,那么输出是6 {{ first|add:second }} ,如果 first 是 [1, 2, 3] 并且 second 是 [4, 5, 6] ,则输出为 [1, 2, 3, 4, 5, 6] 。 - 其他
https://docs.djangoproject.com/zh-hans/4.0/ref/templates/builtins/#ref-templates-builtins-filters
2.2 组件
- 引擎
django模板系统的实例 django.template.Engine - 模板
django已编译的模板,django.template.Template ,模板可以通过Engline.get_template() 获取 - 上下文
django.template.Context 除了上下文数据外,还保存了一些元数据,它会被传递给 Template.render() 来渲染模板 - 加载器
用于加载django模板给人展示界面,django默认使用基于文件系统的模板加载器,settings.py 文件中的默认加载设置,例如:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'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',
],
},
},
]
- 上下文处理器
主要是为了接收httprequest作为参数,并返回一个dict的数据天际到渲染上下文的函数,作用:将所有模板共享的通用数据添加到上下文中,而无需在每个视图中重复代码
- django.contrib.auth.context_processors.auth
- django.template.context_processors.debug
- django.template.context_processors.i18n
- django.template.context_processors.media
- django.template.context_processors.static
- django.template.context_processors.csrf
- django.template.context_processors.request
- django.template.context_processors.tz
- django.contrib.messages.context_processors.messages
详情:https://docs.djangoproject.com/es/4.0/ref/templates/api/#context-processors
3 模板引擎
3.1 配置
模板引擎需要在 settings.py 中的 templates 标签中配置,例如:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'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',
],
},
},
]
- backend : 实现django后端api的模板引擎类的python路径,内置后端是
django.template.backends.django.DjangoTemplates 和 django.template.backends.jinja2.Jinja2 - dirs : 定义引擎按顺序查找模板源文件的目录列表
- app_dirs : 是否应该在已安装的应用程序中查找模板
- options : 后端特定的一些设置
3.2 用法
django.template.loader 模块定义了两个加载模板的函数
- get_template() : 使用给定名称加载模板并返回 Template 对象
- select_template() : 它接受一个模板名称的列表。它按顺序尝试每个名字,并返回第一个存在的模板。
- Template.render() : 使用给定的上下文渲染此模板
- render_to_string() : 减少加载和渲染模板的重复性
- render() : 它调用 render_to_string() ,并将结果提供给 HttpResponse
- engines :
from django.template import engines
django_engine = engines['django']
template = django_engine.from_string("Hello {{ name }}!")
4 内置后端
4.1 DTL - DjangoTemplates
设置 backend 为 django.template.backends.djangoTemplates ,配置django模板引擎 当 app_dirs = True ,djangotemplates 引擎会在已安装的应用程序的 templates 子目录中寻找模板 其中 options 有以下选项:
autoescasep 控制是否启用html自动转义context_processors 当模板被请求渲染时,用于填充上下文的可调用项的点分隔 Python 路径列表debug :开启/关闭模板调试模式的布尔值。loaders :模板加载器类的点分隔 Python 路径列表。string_if_invalid :模板系统对无效变量(如拼写错误)应将此字符串输出file_charset :用于读取磁盘上模板文件的字符集,默认 utf-8libraries :模板标签模块的标签字典和点分隔 Python 路径,用于向模板引擎注册。builtins :要添加的 内置模板标签和过滤器 的点分隔 Python 路径列表
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'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',
],
},
},
]
4.2 Jinja2
设置 backend 为 django.template.backends.jinja2.Jinja2 ,配置django模板引擎 当 app_dirs = True ,jinja2 引擎会在已安装的应用程序的 jinja2 子目录中寻找模板 为了使用 Django 特有的 API,你必须将它们配置到环境中:
from django.templatetags.static import static
from django.urls import reverse
from jinja2 import Environment
def environment(**options):
env = Environment(**options)
env.globals.update({
'static': static,
'url': reverse,
})
return env
TEMPLATES = [
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [BASE_DIR / 'jinja2'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
],
'environment': 'mysite.jinja2.environment',
},
},
]
|