模板层Template
每⼀个 Web 框架都需要⼀种很便利的⽅法⽤于动态⽣成 HTML 页⾯。 最常见的做法是使⽤模板。
模板包含所需 HTML 页⾯的静态部分,以及⼀些特殊的模版语法,⽤于将动态内容插⼊静态部分。
说⽩了,模板层就是如何往 HTML ⽂件中填⼊动态内容的系统。
Django 可以配置⼀个或多个模板引擎(语⾔),也可以不⽤引擎。
Django ⾃带⼀个称为 DTL(Django Template Language )的模板语⾔,以及另外⼀种流⾏的 Jinja2 语⾔(需要提前安装,pip install Jinja2)。
Django 为加载和渲染模板定义了⼀套标准的 API,与具体的后台⽆关。加载指的是,根据给定的模版名称找到模板然后预处理,通常会将它编译好放在内存中。渲染则表⽰,使⽤ Context 数据对模板插值并返回⽣成的字符串。
DTL 作为 Django 原⽣的模板系统,⼀直到 Django1.8,都是唯⼀的内置模板系统。如果没有特别重要的理由,需要选择另外⼀种模板系统的话,建议坚持使⽤ DTL。
Django 很多内部组件都使⽤了 DTL,例如 ib.admin,如果你不想让它们罢⼯,或者花费⼤⼒⽓进⾏修改,不要放弃 DTL。⼀、配置引擎
模板引擎通过 ttings 中的 TEMPLATES 设置来配置。这是⼀个列表,与引擎⼀⼀对应,每个元素都是⼀个引擎配置字典。由startproject 命令⽣成的ttings.py 会⾃定定义如下的值:
TEMPLATES = [
{
'BACKEND': 'plate.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
# ... some options here ...
},
物流案例
},
]
BACKEND:后端。
内置的后端有 plate.backends.django.DjangoTemplates 和plate.backends.jinja2.Jinja2。
我将
OPTIONS 中包含了具体的后端设置。
由于绝⼤多数引擎都是从⽂件加载模板的,所以每种模板引擎都包含两项通⽤设置:
1.DIRS:定义了⼀个⽬录列表,模板引擎按列表顺序搜索这些⽬录以查找模板源⽂件。
2.APP_DIRS:告诉模板引擎是否应该进⼊每个已安装的应⽤中查找模板。通常请将该选项保持为 True。
每种模板引擎后端都定义了⼀个惯⽤的名称作为应⽤内部存放模板的⼦⽬录名称。(例如 Django 为它⾃⼰的模板引擎指定的是
大疆老板
‘templates’,为 jinja2 指定的名字是‘jinja2’)。尤其是,django 允许你有多个模板引擎后端实例,且每个实例有不同的配置选项。 在这种情况下你必须为每个配置指定⼀个唯⼀的 NAME .
DTL 引擎的 OPTIONS 配置项中接受以下参数:
1.'autoescape':⼀个布尔值,⽤于控制是否启⽤ HTML ⾃动转义功能。默认为 True。
2.context_processors: 以"."为分隔符的 Python 调⽤路径的列表。默认是个空列表。
3.'debug':打开/关闭模板调试模式的布尔值。默认和 tting 中的 DEBUG 有相同的值。
4.'loaders':模板加载器类的虚拟 Python 路径列表。默认值取决于 DIRS 和APP_DIRS 的值。
5.string_if_invalid:⾮法变量时输出的字符串。默认为空字符串。
6.file_chart:⽤于读取磁盘上的模板⽂件的字符集编码。默认为 FILE_CHARSET的值。
7.'libraries':⽤于注册模板引擎。 这可以⽤于添加新的库或为现有库添加备⽤标签。
8.'builtins':以圆点分隔的 Python 路径的列表。
⼆、简单的⽤法
get_template(template_name,using = None)
该函数使⽤给定的名称查找和加载模板,并返回⼀个 Template 对象。
模板的查找和加载机制取决于每种后端引擎和配置,如果想使⽤指定的模板引擎进⾏查找,请将模板引擎的 NAME 赋给 get_template 的using 参数。
lect_template(template_name_list,using = None)
和 get_template()相似, 只不过它使⽤包含模板名称的列表作为参数。
由 lect_template()和 get_template()返回的 Template 对象都必须提供⼀个 render()⽅法,如下所⽰:
通过给定的 context 对该模板进⾏渲染。
如果提供了 context,那么它必须是⼀个 dict 对象。如果要提供 request 参数 ,必须使⽤ HttpReques
t 对象。
针对下⾯的 TEMPLATES 配置,对模版⽂件的搜索顺序和路径如下:
TEMPLATES = [
{
'BACKEND': 'plate.backends.django.DjangoTemplates',
'DIRS': [
'/home/',
'/home/html/default', ], }, {
'BACKEND': 'plate.backends.jinja2.Jinja2',
'DIRS': [
'/home/html/jinja2',
],
},
]
如果你调⽤函数 get_template('story_detail.html'), Django 将按以下顺序查找story_detail.html:
/home//story_detail.html('django'引擎)
/home/html/default/story_detail.html('django'引擎)
/home/html/jinja2/story_detail.html('jinja2'引擎)
如果你调⽤函数 lect_template(['story_253_detail.html','story_detail.html']),Django按以下顺序查找:
/home//story_253_detail.html('django'引擎)
/home/html/default/story_253_detail.html('django'引擎)
/home/html/jinja2/story_253_detail.html('jinja2'引擎)
/home//story_detail.html('django'引擎)
/home/html/default/story_detail.html('django'引擎)
/home/html/jinja2/story_detail.html('jinja2'引擎)
注意:Django 查找到任何⼀个匹配的模板后便停⽌搜寻,所以这是个类似 url 搜索的短路操作!
强调:前⾯我们介绍过,建议在每个 APP 的的模版⼦⽬录下都建⽴⼀个⼦⽬录来唯⼀对应这个 APP。这样做可以增强你的 APP 的可⽤性。 将所有的模版⽂件放在根模版⽬录下会引发混淆。
要在⼀个⼦⽬录内加载模板,像下⾯这样:
get_template('news/story_detail.html')
如果结合上⾯例⼦中的 TEMPLATES 配置,这将会尝试按顺序查找并加载下列模板︰
/home//news/story_detail.html('django'引擎)
/home/html/default/news/story_detail.html('django'引擎)
/home/html/jinja2/news/story_detail.html('jinja2'引擎)
另外,为了减少加载模板、渲染模板等重复⼯作,django 提供了处理这些⼯作的快捷函数。
render_to_string(template_name, context=None, request=None,using=None)[source]
render_to_string()会像 get_template()⼀样加载模板并⽴即调⽤ render()⽅法。 它需要以下参数。
1.TEMPLATE_NAME:要加载的模板的名称或列表。
2.context:要⽤作模板的上下⽂进⾏渲染的数据字典,也就是你要插⼊的动态数据字典。
宫非宫 3.request:可选的 HttpRequest 对象。
4.using:指定使⽤的模板引擎 NAME。 搜索模板将仅限于该引擎。
⽤法⽰例:
plate.loader import render_to_string
rendered = render_to_string('my_template.html', {'foo': 'bar'})
三、基本语法
Django 模板语⾔(DTL)的语法包括四种结构。
1. 变量
变量的值来⾃ context 中的数据字典, 类似于字典对象的 keys 到 values 的映射关系。
变量是被}}和{{括起来的部分,例如:
My first name is {{ first_name }}. My last name is {{ last_name }}.
当模版引擎遇到⼀个变量,它将从上下⽂ context 中获取这个变量的值,然后⽤值替换掉它本⾝。假如有⼀个上下⽂{'first_name': 'John', 'last_name': 'Doe'},模板渲染后的真实值为:
My first name is John. My last name is Doe.
变量的命名包括任何字母数字以及下划线("_")的组合。点(".")也有可能会在变量名中出现,不过它有特殊的含义。最重要的是,变量名称中不能有空格或标点符号。
当模版系统遇到点("."),它将以这样的顺序查询这个圆点具体代表的功能:
1.字典查询(Dictionary lookup)
2.属性或⽅法查询(Attribute or method lookup)
3.数字索引查询(Numeric index lookup)
如果你使⽤的变量不存在,模版系统将插⼊ string_if_invalid 选项的值,默认设置为''(空字符串)。
2. 标签
模版语⾔中的标签类似 Python 中的函数,功能多样,使⽤灵活。可以输出内容、控制结构,甚⾄可以访问其他的模板标签。
标签是由%}和{%来定义的,例如:
{% csrf_token %} # csrf 令牌标签
⼤部分标签都接受参数:
{% cycle 'odd' 'even' %} # 循环使⽤'odd'和'even'
部分标签需要使⽤起始和闭合标签,典型代表为 for 循环标签和 if 判断标签:
{% if ur.is_authenticated %}Hello, {{ ur.urname }}.{% endif %}
纸老虎打一成语
Django ⾃带了⼤约 24 个内置的模版标签。下⾯是⼀些常⽤的标签:
2.1. for 循环标签
循环对象中每个元素。需要结束标签{% endfor %} 。例如,显⽰ athlete_list中提供的运动员列表:
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
2.2. if,elif 和 el 标签
计算⼀个表达式,并且当表达式的值是“True”时,显⽰块中的内容。需要{%endif %}结束标签。整体逻辑⾮常类似 Python 的 if、elif 和 el,如下所⽰。:
{% if athlete_list %}
Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
Athletes should be out of the locker room soon!
{% el %}
No athletes.
{% endif %}
在上⾯的例⼦中,如果 athlete_list 不是空的,运动员的数量将显⽰为{{ athlete_list|length }}。否则,如果 athlete_in_locker_room_list 不为空,将显⽰“Athletes should be out…”。如果两个列表都是空的,将显⽰“No athletes.” 。
还可以在 if 标签中使⽤过滤器和多种运算符:
{% if athlete_list|length > 1 %}
Team: {% for athlete in athlete_list %} ... {% endfor %}
{% el %}
Athlete: {{ athlete_list.0.name }}
{% endif %}
需要注意,⼤多数模版过滤器都返回字符串类型,所以使⽤过滤器做整数类型的⽐较通常是错误的,但 length 是⼀个例外。
2.3. block 和 extends 标签
继承和复写模版。类似 Python 的类继承和重写机制。
3. 过滤器
过滤器看起来是这样的:{{ name|lower }}。使⽤管道符号(|)来应⽤过滤器。该过滤器将⽂本转换成⼩写。
过滤器可以“链接”。⼀个过滤器的输出应⽤于下⼀个过滤器。例如:
{{ text|escape|linebreaks }}就是⼀个常⽤的过滤器链,它⾸先转移⽂本内容,然后把⽂本⾏转成<p>标
签。
⼀些过滤器带有参数。 过滤器的参数看起来像是这样: {{ bio|truncatewords:30 }}。这将显⽰ bio 变量的前 30 个词。
过滤器参数包含空格的话,必须⽤引号包起来。例如,使⽤逗号和空格去连接⼀个列表中的元素,你需要使⽤{{ list|join:", " }}。
Django 提供了⼤约六⼗个内置的模版过滤器,很多时候你想要的功能,它都已经提供了,有需要的时候就去查⼀下吧。下⾯是⼀些常⽤的模版过滤器:
3.1. default
为 fal 或者空变量提供默认值,像这样:
{{ value|default:"nothing" }}
3.2. length
返回值的长度。它对字符串和列表都起作⽤。
{{ value|length }}
如果 value 是['a', 'b', 'c', 'd'],那么输出 4。
3.3. filesizeformat
格式化为“⼈类可读”⽂件⼤⼩单位(即'13 KB',4.1 MB','102 bytes'等)。成都规划局
{{ value|filesizeformat }}
如果 value 是 123456789,输出将会是 117.7MB。
4. 注释
模版语⾔的注释看起来像这样:
{# this won't be rendered #} # 单⾏注释
{% comment %}标签提供多⾏注释功能。
附:
人人为我
Django 内置标签总览
可以查询下表来总览 Django 的内置标签:
标签说明
autoescape⾃动转义开关
block块引⽤
comment注释圬工桥
csrf_token CSRF 令牌
cycle循环对象的值
debug调试模式
extends继承模版
filter过滤功能
firstof输出第⼀个不为 Fal 的参数
for循环对象
for … empty带 empty 说明的循环