(笔记持续更新)
官方网址
目录
Templates(模板)
作为一个前端框架,Django需要一种便捷的方法去动态生成HTML。最常用的方法就是templates。一个templates包含html的静态部分一级动态内容插入的特定方法。具体可参考官网教程3
一个Django项目可以配置0到多个模板。Django不仅为自己的模板系统提供了内置的后端,被叫做the Django template language (DTL),也为现在较流行的JinJa2提供了内置的后端。其他模板语言可以从第三方获取后台支持。当然,你也可以自己来定制后端
Django定义了一个标准API,用于Loading和Rendering模板,而不考虑后端。Loading包括查找给定标识符的模板并对其进行预处理,通常将其编译为内存中的表示。Rendering是指在模板中插入数据,并返回结果字符串。
The Django template language
语法
一个Django模板是一个由DTL组成的文本文档或者是python字符串。其中一些设计被认为或理解成模板引擎。最主要的就是变量和标签。
当模板和文档一起呈现时,变量的值代替变量名,标签被查找执行,剩下的原样输出。
Django的模板语言语法包含四个部分
1、Variables变量
变量名可以是字母、下划线,但下划线不可以是变量名开头,因为以下划线为开头的变量通常被认为是私有变量,不被访问。注意,变量名中不可以有空格或者其他标点符号。
当render内容为以下情况时
{'first_name': 'John', 'last_name': 'Doe'}
模板及返回结果如下
My first name is {{ first_name }}. My last name is {{ last_name }}.
返回结果:
My first name is John. My last name is Doe.
字典查找、属性查找和列表索引查找使用点表示法实现:
{{ my_dict.key }}
{{ my_object.attribute }}
{{ my_list.0 }}
2、Tags标签
形式{%and%}
标签的定义是模糊的。比如,一个标签能够输出内容,可以作为一个控制结构(如if、for),获取数据库内容,甚至能够访问其他模板标签。
- 基本形式的标签例子
{% csrf_token %}
- 可接受参数的标签例子
{% cycle 'odd' 'even' %}
- 需要开始结束标签的例子
{% if user.is_authenticated %}Hello, {{ user.username }}.{% endif %}
3、Filters滤波器
滤波器用于转换变量和标签参数的值
例如
render内容为
{'django': 'the web framework for perfectionists with deadlines'}
滤波器及返回结果如下
滤波器:{{ django|title }},作用是转换django变量中每个单词的首字母为大写。
返回结果:The Web Framework For Perfectionists With Deadlines
注释
单行注释:
{# this won't be rendered #}
多行注释
<p>Rendered text with {{ pub_date|date:"c" }}</p>
{% comment "Optional note" %}
<p>Commented out text with {{ create_date|date:"c" }}</p>
{% endcomment %}
组件
组间是指DTL的API,详细内容请查看API reference
1、Engine
django.template.Engine 封装了the Django template system的一个实例。直接实例化Engine是为了在Django项目外使用DTL。
django.template.backends.django.DjangoTemplates 是为了Django的模板后端API能够适应django.template.Engine的一个简单的封装。
2、Template
django.template.Template 是一个被编译的模板. 可通过 Engine.get_template() 或者 Engine.from_string()来获得模板.
同样的, django.template.backends.django.Template了Django的模板后端API能够适应 django.template.Template 的一个简单的封装。
3、Context
django.template.Context保存了一些元数据。这些数据传递给Template.render()
Context用于存储当前的HttpRequest并运行程序。django.template.RequestContext 是Context的一个子类。
数据是通过字典的形式进行传递,如果需要的话HttpRequest也会单独被传递。
4、Loaders
Loaders被用来定位、加载模板,返回模板对象。
loaders列表,自定义loaders
5、Context processors
Context processors是一个接受当前HTTpRequest,返回一个字典数据的函数。
它们的主要用途是将所有模板共享的公共数据添加到上下文中,而无需在每个视图中重复代码。
Context processors列表,当然,i也可以实现属于你自己的Context processors
模板引擎的支持
配置
使用setting.py中的TEMPLATES项对模板引擎进行配置。以下是一个配置列表,每个引擎都有一个这样的配置列表。默认值是空值。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
# ... some options here ...
},
},
]
- BACKEND,是一个实现Django模板后端API的模板引擎路径。内置的后端是django.template.backends.django.DjangoTemplates和django.template.backends.jinja2.Jinja2
因为大多数引擎从文件中加载模板,所以每个引擎的顶级配置都包含两个常见设置 - DIRS,定义了一个模板路径的列表,引擎将从列表路径中查找模板资源文件。
- APP_DIRS,告诉引擎是否应在以安装的应用中查找模板。每个后端为应用程序中的子目录定义了一个常规名称,该子目录的模板应该存储在其中
尽管很少使用,有时也会用不同的选项来配置同一后端的几个实例。在这种情况下,应该为每个引擎定义一个单独的名字。 - OPTIONS,包含了后端特定的配置。
用法
django.template.loader给出了加载模板的两个方法。
1)get_template(template_name, using=None)
这个方法是根据给出的模板名称来加载模板项。
返回值的类型取决于加载模板的后端。每个后端都有一个属于自己的模板类型。
该方法回去调取每一个模板引擎,直到成功。如果模板找不到,就会报TemplateDoesNotExist错误。如果模板找到了,但是存在语法上的错误,就会报TemplateSyntaxError。
无论是模板的搜索还是下载,都是依赖每个引擎的后端和配置。如果你想要限定模板搜索引擎,可以通过讲引擎名传给using项来实现。
2)select_template(template_name_list, using=None)
该方法与get_temple的区别在于,输入参数为模板名称列表。该函数会按顺序返回每个模板名称对应的模板。
get_template() 和select_template()返回的模板对象必须提供一个render()方法。
Template.render(context=None, request=None)
该方法返回模板的内容。
其中,context必须是字典,否则引擎讲提供一个内容为空的模板;request必须是一个HttpRequest。然后,引擎必须使它以及CSRF令牌在模板中可用。如何实现这一点取决于每个后端。
以下是一个模板配置的用例
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将从以下路径中搜索。
- /home/html/example.com/story_detail.html (‘django’ engine)
- /home/html/default/story_detail.html (‘django’ engine)
- /home/html/jinja2/story_detail.html (‘jinja2’ engine)
如果使用方法select_template([‘story_253_detail.html’, ‘story_detail.html’]),Django将从以下路径中搜索。
- /home/html/example.com/story_253_detail.html (‘django’ engine)
- /home/html/default/story_253_detail.html (‘django’ engine)
- /home/html/jinja2/story_253_detail.html (‘jinja2’ engine)
- /home/html/example.com/story_detail.html (‘django’ engine)
- /home/html/default/story_detail.html (‘django’ engine)
- /home/html/jinja2/story_detail.html (‘jinja2’ engine)
当发现有效模板时,Django就会停止搜索。
最好在组织模板时使用清晰的子目录。惯例是为每个Django应用程序创建一个子目录,根据需要在这些子目录中添加子目录。获取带有子目录的模板例子及对应搜索路径如下
get_template('news/story_detail.html')
- /home/html/example.com/news/story_detail.html (‘django’ engine)
- /home/html/default/news/story_detail.html (‘django’ engine)
- /home/html/jinja2/news/story_detail.html (‘jinja2’ engine)
此外,为了减少加载和呈现模板的重复性,Django提供了一个快捷函数来自动化这个过程。
render_to_string(template_name, context=None, request=None, using=None)
render_to_string()像 get_template()一样来加载模板,调用render()方法。
- template_name, 加载模板的名字,如果输入是一个列表,Django将会调用select_template()来搜索模板。
- context,字典类型,用于呈现模板内容
- request, HrrpRequest
- using,指定模板引擎名,若不设置,则依次搜索引擎。
内置后端
class DjangoTemplates
BACKEND,设置为‘django.template.backends.django.DjangoTemplates’,用来配置Django 模板引擎。
当APP_DIR=True, Django模板引擎就会在安装应用的子路径中搜索模板。
OPTIONS,可接受的参数如下。
- ‘autoescape’:boolean类型,是否启用了HTML自动转义。默认是True。注意,只有当返回的模板非html模板时才可以设置该项为False
- ‘context_processors’: 带点的python路径里列表。默认是空列表
- ‘debug’
- ‘loaders’
- ’string_if_invalid’
- ’file_charset’
- ’libraries’
- ’builtins’