1 模板渲染过程
模板处理分为两个过程:
- 加载模板
- 渲染模板
查看源码:
def render(request, template_name, context=None, content_type=None, status=None, using=None):
""" Returns a HttpResponse whose content is filled with the result of calling django.template.loader.render_to_string() with the passed arguments. """
content = loader.render_to_string(template_name, context, request, using=using)
return HttpResponse(content, content_type, status)
def render_to_string(template_name, context=None, request=None, using=None):
""" Loads a template and renders it with a context. Returns a string. template_name may be a string or a list of strings. """
if isinstance(template_name, (list, tuple)):
template = select_template(template_name, using=using)
else:
template = get_template(template_name, using=using) # 关键
return template.render(context, request) # 关键
所以我们可以转化为:
def hellotemplate(request):
#return render(request,'HelloTemplate.html')
template = loader.get_template('HelloTemplate.html') # 1.加载模板
content = template.render() # 2.渲染模板
return HttpResponse(content)
2 模板组成
模板主要有两部分组成:
- HTML静态代码
- 动态插入的代码段(挖坑、填坑)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>StudentList</title>
</head>
<body>
<ul>
{% for student in students %}
<li>{{student.s_name}}</li> # 挖坑
{% endfor %}
</ul>
</body>
</html>
模板中的动态代码段除了做基本的静态填充,还可以实现一些基本的运算、转换和逻辑。
模板中的变量:
- 视图传递给模板的数据
- 遵循标识符规则
- 语法
{{var}}
- 如果变量不存在,则插入空字符串
3 模板语法
3.1 点语法
模板中的点语法可以有三种用途:
- 字典查询,充当字典中的key
- 属性或者方法
- 索引
模板中的小弊端,调用对象的方法不能传参。
演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Employees</title>
</head>
<body>
员工列表:
<ul>
{% for employee in employees %}
<li>{{ employee.e_name }}</li> # 访问属性
{% endfor %}
</ul>
---------------------
<br>
{{ employees.0.e_name }} # 访问索引
</body>
</html>
输出:
3.2 模板标签(控制语句)
if/else 标签
基本语法格式如下:
{% if condition %}
... display
{% endif %}
或者
{% if condition %}
... display1
{% else %}
... display2
{% endif %}
或者
{% if condition1 %}
... display 1
{% elif condition2 %}
... display 2
{% else %}
... display 3
{% endif %}
for 标签
{% for %} 允许我们在一个序列上迭代。
与Python的 for 语句的情形类似,循环语法是 for X in Y ,Y是要迭代的序列而X是在每一个特定的循环中使用的变量名称。
每一次循环中,模板系统会渲染在 {% for %} 和 {% endfor %} 之间的所有内容。
<ul>
{% for 变量 in 列表 %}
语句1
{% empty %}
语句2
{% endfor %}
</ul>
当列表为空或者不存在时,执行empty之后的语句。
forloop标签
{{forloop.count}} 表示当前第几次循环,从1开始
{{forloop.count0}} 表示当前第几次循环,从0开始
{{forloop.revcount}} 表示当前第几次循环,倒着数数,到1结束
{{forloop.revcount0}} 表示当前第几次循环,倒着数数,到0结束
{{forloop.first}} 是否是第一个 Bool
{{forloop.last}} 是否是最后一个 Bool
注释标签
Django 单行注释使用 {# #}。
{# 这是一个注释 #}
Django 多行注释使用 {% comment %}。
{% comment %}
内容
{% endcomment %}
过滤器
模板过滤器可以在变量被显示前修改它,过滤器使用管道字符,如下所示:
{{var | 过滤器}}
过滤器的种类:
add {{p.page|add:5}} +5
add {{p.page|add:-5}} -5
upper {{student.name|upper}} 大写
lower {{student.name|lower}} 小写
过滤器可以传递参数,参数使用引号引起来:
比如:join {{students|join '='}}
根据指定格式转换日期为时间字符串
{{dateVal|date:'y-m-d'}}
过滤管道可以被套接,既是说,一个过滤器管道的输出又可以作为下一个管道的输入:
{{ my_list|first|upper }}
include标签
{% include %} 标签允许在模板中包含其它的模板的内容。
缺点
:效率不如block+extends高。
编写add.html
<p>我来自另一个html文件的内容</p>
在另一个html添加,并访问
{% include 'add.html' %}
效果如下:
4 模板继承
模板可以用继承的方式来实现复用。
4.1 用例
接下来我们先创建之前项目的 templates 目录中添加 base.html 文件,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>电商站点</title>
</head>
<body>
<p>我是一个基本网页框架</p>
{% block header %}
{% endblock %}
{% block banner %}
{% endblock %}
{% block content %}
{% endblock %}
{% block footer %}
{% endblock %}
</body>
</html>
编写home.html:
{% extends 'base.html' %}
{% block banner %}
<p>我是一个banner</p>
{% endblock %}
{% block content %}
<p>我是正文!</p>
{% endblock %}
添加路由、视图函数,并访问
urlpatterns=[
url(r'^home/', views.home),
]
def home(request):
return render(request,'home.html')
效果展示:
4.2 结构标签
block
- 块
- 用来规划我们的布局(挖坑)
- 首次出现代表规划
- 第二次出现代表填充以前的规划
- 第三次出现代表填充以前的规划,默认动作是覆盖(重写)
- 如果不想覆盖,请填写
{{block.super}}
- 这样就实现了增量式操作
- 如果不想覆盖,请填写
用例
编写home2.html
{% extends 'home.html' %}
{% block banner %} # 第三次出现,默认重写
<p>我是被重写过的banner</p>
{% endblock %}
{% block content %}
{{ block.super }} # 增量语句
<p>我是增量后的正文!</p>
{% endblock %}
效果如下:
extends
- 继承
- 可以获取父模板中的所有结构