每个Web框架都须要一种很便利的方法用于动态生成HTML页面。 最多见的作法是使用模板。html
模板包含所需HTML页面的静态部分,以及一些特殊的模版语法,用于将动态内容插入静态部分。web
说白了,模板层就是如何往HTML文件中填入动态内容的系统。django
Django能够配置一个或多个模板引擎(语言),也能够不用引擎。后端
Django自带一个称为DTL(Django Template Language )的模板语言,以及另一种流行的Jinja2语言(须要提早安装,pip install Jinja2)。框架
Django为加载和渲染模板定义了一套标准的API,与具体的后台无关。加载指的是,根据给定的模版名称找到的模板而后预处理,一般会将它编译好放在内存中。渲染则表示,使用Context数据对模板插值并返回生成的字符串。函数
DTL做为Django原生的模板系统,一直到Django1.8,都是惟一的内置模版系统,可能你对它有些意见,可是它仍然是一个优秀的模版库。若是没有特别重要的理由,须要选择另一种模版系统的话,建议坚持使用DTL,特别是在编写可插拔的应用并打算发布其模板的时候。Django不少内部组件都使用了DTL,例如django.contrib.admin
,若是你不想让它们罢工,或者花费大力气进行修改,不要放弃DTL。post
模板引擎经过settings中的TEMPLATES
设置来配置。这是一个列表,与引擎一一对应,每一个元素都是一个引擎配置字典。由startproject命令生成的settings.py
会自定定义以下的值:ui
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { # ... some options here ... }, }, ]
BACKEND:后端。内置的后端有django.template.backends.django.DjangoTemplates
和django.template.backends.jinja2.Jinja2
。this
OPTIONS中包含了具体的后端设置。编码
因为绝大多数引擎都是从文件加载模板的,因此每种模板引擎都包含两项通用设置:
每种模板引擎后端都定义了一个惯用的名称做为应用内部存放模板的子目录名称。(例如Django为它本身的模板引擎指定的是 ‘templates’,为jinja2指定的名字是‘jinja2’)。尤为是,django容许你有多个模板引擎后端实例,且每一个实例有不一样的配置选项。 在这种状况下你必须为每一个配置指定一个惟一的NAME .
DTL引擎的OPTIONS配置项中接受如下参数:
context_processors
: 以"."为分隔符的Python调用路径的列表。默认是个空列表。APP_DIRS
的值。string_if_invalid
:非法变量时输出的字符串。默认为空字符串。file_charset
:用于读取磁盘上的模板文件的字符集编码。默认为FILE_CHARSET
的值。django.template.loader
中定义了两个函数以加载模板。
get_template(template_name,using = None)[source]
该函数使用给定的名称查找和加载模板,并返回一个Template对象。
模板的查找和加载机制取决于每种后端引擎和配置,若是想使用指定的模板引擎进行查找,请将模板引擎的NAME赋给get_template
的using参数。
select_template(template_name_list,using = None)[source]
和get_template()类似, 只不过它使用包含模板名称的列表做为参数。
由select_template()
和get_template()
返回的Template对象都必须提供一个render()方法,以下所示:
Template.render(context=None, request=None)
经过给定的context对该模板进行渲染。
若是提供了context,那么它必须是一个dict对象。若是要提供request参数 ,必须使用HttpRequest对象。
针对下面的TEMPLATES配置,对模版文件的搜索顺序和路径以下:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ '/home/html/example.com', '/home/html/default', ], }, { 'BACKEND': 'django.template.backends.jinja2.Jinja2', 'DIRS': [ '/home/html/jinja2', ], }, ]
若是你调用函数get_template('story_detail.html')
, Django将按如下顺序查找story_detail.html
:
/home/html/example.com/story_detail.html('django'引擎) /home/html/default/story_detail.html('django'引擎) /home/html/jinja2/story_detail.html('jinja2'引擎)
若是你调用函数select_template(['story_253_detail.html','story_detail.html'])
,Django按如下顺序查找:
/home/html/example.com/story_253_detail.html('django'引擎) /home/html/default/story_253_detail.html('django'引擎) /home/html/jinja2/story_253_detail.html('jinja2'引擎) /home/html/example.com/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/html/example.com/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()
方法。 它须要如下参数。
用法示例:
from django.template.loader import render_to_string rendered = render_to_string('my_template.html', {'foo': 'bar'})
之后,若是没有特别强调,都是针对DTL引擎。
Django模板语言的语法包括四种结构。
变量的值来自context中的数据字典, 相似于字典对象的keys到values的映射关系。
变量是被}}
和{{
括起来的部分,例如:
My first name is {{ first_name }}. My last name is {{ last_name }}.
假若有一个上下文{'first_name': 'John', 'last_name': 'Doe'}
,模板渲染后的真实值为:
My first name is John. My last name is Doe.
字典查询,属性查询和列表索引查找都是经过圆点符号.
来实现。因此圆点在模版引擎中是万能的上帝,不知道该怎么写下去的时候,就尝试点点点....:
{{ my_dict.key }} {{ my_object.attribute }} {{ my_list.0 }}
模版语言中的标签相似Python中的函数,功能多样,使用灵活。能够输出内容、控制结构,甚至能够访问其余的模板标签。
标签是由%}
和{%
来定义的,例如:
{% csrf_token %} # csrf令牌标签
大部分标签都接受参数:
{% cycle 'odd' 'even' %} # 循环使用'odd'和'even'
部分标签须要使用起始和闭合标签,典型表明为for循环标签和if判断标签:
{% if user.is_authenticated %}Hello, {{ user.username }}.{% endif %}
过滤器用于修改变量或标签参数的值。例以下面这样:
{{ django|title }}
若是有一个上下文{'django': 'the web framework for perfectionists with deadlines'}
,那么模板最终呈现:
The Web Framework For Perfectionists With Deadlines # 全部的单词首字母大写了
有些过滤器还接收一个参数:
{{ my_date|date:"Y-m-d" }} # 按指定的格式"Y-m-d",显示日期
模版语言的注释看起来像这样:
{# this won't be rendered #} # 单行注释
{% comment %}
标签提供多行注释功能。
详细教程