Django之模板
模板是啥?
就是一种动态生成HTML页面的快捷方式
1、模板与模板引擎
模板文件就是一个文本文件(如html、csv等),但通常html多一点。
- 模板与模板引擎的关系:
模板引擎-----解释------->模板文件
- 模板引擎:
有Django自己内置的,也支持Jinja2
前期配置
需先在settings.py文件中的TEMPLATES选项中配置模板引擎。
示例:
TEMPLATES = [
{
'BACKEND':'django.template.backends.django.DjangoTemplates',
'DIRS':[],
'APP_DIRS':True,
'OPTIONS':{
...
},
},
]
-
BACKEND:模板引擎类的路径。常见两种引擎的路径:
Django内置引擎DjangoTemplates-------django.template.backends.django.DjangoTemplates
Jinja2引擎---------------------django.template.backends.jinja2.Jinja2
-
DIRS:设置模板源文件的目录列表,模板引擎将按列表中元素的顺序依次查找目录。
-
APP_DIRS:声明是否在已安装的应用程序中查找模板
-
OPTIONS:模板引擎的设置信息,dict类型。
加载模板
get_template(template_name, using=None)-----------接收一个模板名,返回Template对象
select_template(template_name_list, using=None)----------接收一个模板名称列表,按顺序尝试加载列表中的模板,返回找到的第一个模板的Template对象。
注:using为可选参数
渲染Template对象的render方法:
Template.render(context=None, request=None)
#context 接收一个字典,内容为将要嵌入到模板中的上下文,可为空
#request 是一个HttpRequest对象
render_to_string()函数像get_template()一样加载模板,并立刻调用render()方法。
2、模板查找顺序
TEMPLATES = [
{
'BACKEND':'diango.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”,模板引擎查找模板的顺序如下:
/home/html/example.com/story_detail.html (Django引擎)
/home/html/default/story_detail.html (Django引擎)
/home/html/jinja2/story_detail.html (Jinja2引擎)
使用select_template()方法加载模板,每个元素的加载顺序与上面一样。
3、模板语言
变量
形如{{variable}}
模板中的变量在调用方法时,只写方法名不写括号。
例如变量books调用items()方法,则为{{books.items}}
过滤器
过滤器用于过滤变量
形如:{{variables|filters}}或{{variables|filters1|filters2…}}
接收参数:冒号分割{{variables|join:", "}}
内置过滤器有60多个
如:
add ------------- {{value|add:“32”}} #若value为12,则过滤后为44
add ----------- {{first|add:second}} #若first为[1,2,3],second为[4,5,6]则过滤后为[1,2,3,4,5,6]
capfirst,center, cut, date, default, dictsort, escape, filesizeformat, join, length, linenumbers, lower/upper, random, truncatewords等
标签
相当于具有开始和结尾的逻辑代码。
形如:
{% tag %}
...
{% endtag %}
内置了六十多个模板标签。
-
for循环
{% for book in book_list %} <li>{{book.name}}<li> {% endfor %}
# 反向遍历列表 {% for obj in list reversed %}
# 遍历层列表 {% for x, y in points %} There is a point at {{x}},{{y}} {% endfor %}
# 遍历字典 {% for key, value in data.items %} {{key}}:{{value}} {% endfor %}
-
for…empty
{% for book in book_list %} <li>{{book.title}}<li> {% empty %} <li>抱歉,图书列表为空</li> {% endfor %}
-
if/elif/else
-
include 加载其他模板
-
load 加载自定义模板标签和过滤器
-
from 加载部分标签和过滤器
-
now 显示当前日期(可格式化)
-
url 返回与给定视图和可选参数匹配的绝对路径
-
autoescape 控制当前自动转义行为(html转义)
-
blok 定义可由模板覆盖的快
-
comment 注释
-
cycle 循环取参
-
extends 标记当前模板所继承的模板
-
firstof 输出变量中第一个非False参数
-
with 为复杂变量创建别名
自定义过滤器和标签
通常位于应用目录包templatetags之下,被load标签加载到模板(要避免重名)
示例:加载filter.py文件
{% load filters %}
注:包含自定义标签的应用需被注册到INSTALLED_APPS中
每个过滤器文件必须包含模块级变量register,示例:
from django import template
register = template.Library()
-
自定义过滤器
自定义过滤器文件filter.py:
from django import template register = template.Library() def sum(value, arg): #自定义过滤器 return value + arg register.filter('sum', sum) #注册自定义的过滤器 #filter(过滤器名,函数名)
#另一种注册方法 @register.filter(name='examp') def examp(value, arg): return value + arg #若过滤器名和函数名相同,也可省略为 @register.filter def examp(value, arg): return value + arg
-
自定义标签
4、模板继承
本质上就是为了提高代码利用率,降低重复率。
父模板:base.html
<!DOCTYPE html>
<html lang='en'>
<head>
<link rel="stylesheet" href="style.css">
<title>{% block title %}页面标题{% endblock %}</title>
</head>
<body>
{% block header %}
<h1>标题</h1>
{% endblock header %}
</body>
</html>
子模版:lists.html
{% extends 'base.html' %} #引入继承文件
{% block title %}
列表页面
{% endblock %}
子模版要想对继承后的父模板进行改动,只需将需改动的继承块重写就行。
5、Jinja2
该引擎于Django内置的差别不大,设计思想也是源于Django内置的引擎。
需要单独安装和配置
与Django在使用上的不同:
-
方法调用
#内置的一定省去括号 {% for page in user.get_created_pages %} ... {% endfor %} #Jinja2一定不能省 {% for page in user.get_created_pages() %} ... {% endfor %}
-
过滤器参数
#内置 {{items|join:", "}} #Jinja2 {{items|join(', ','arg')}}
-
循环
内置:forloop
Jinja2:loop
-
cycle
#内置 {% for user in users %} <li class="{% cycle 'odd' 'even' %}">{{user}}</li> {% endfor %} #Jinja2 {% for user in users %} <li class="{{loop.cycle('odd', 'even')}}">{{user}}</li> {% endfor %}