1.语法
1.1.变量
变量从上下文中输出一个值,上下文是一个类似于字典的对象,将键映射到值。
变量被双括号包围:
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.
1.2.标签
模板标签的形式为{% tagname %},模板标签与业务逻辑相关,有些标签名(tagname)在形式上与程序代码相似,模板标签可以让HTML文件中的内容按照业务逻辑或流程控制进行显示。模板标签也分内置模板标签和自定义模板标签。
1.2.1内置模板标签:
(1)模板标签if用于判断,虽然它放在HTML文件中,但其语法与Python代码语法非常相似。{% if %}为真,模板系统就显示{% if %}和{% endif %}之间的内容。模板标签if可以包含{% else %}、{% elif %}子句。
{% if num>8 %}
num数值大于8
{% elif num<8 %}
num数值小于8
{% else %}
num肯定等于8
{% endif %}
if语句支持==、>、<、!=、<=、>=、and、or、in、not in、is、is not等判断运算符
(2) 模板标签ifequal和ifnotequal也用于判断,一个用于判断两个值是否相等,一个用于判断两个值是否不相等。
<!-- 比较age是否等于80 -- >
{% ifequal age 80 %}
<h3>高寿,祝您健康!</h3>
{% endifequal %}
(3){% for %}用于循环可迭代变量,每次循环时显示{% for %}和{%endfor %}之间的内容。
{% for user in user_list %}
{{ user.name }
{% empty %}
# 判断列表为空没有用户
{% endfor %}
for循环存在内置参数,它们都是为了取得for循环的索引值:
forloop.counter:从1开始返回当前循环的索引值。
forloop.counter0:从0开始返回当前循环的索引值。
forloop.revcounter:返回当前循环的倒序索引值,从最大索引值起始,最后到值1。forloop.revcounter0:返回当前循环的倒序索引值,从最大索引值起始,最后到值0。forloop.first:返回布尔值,表示当前循环是不是第一次循环。
forloop.last:返回布尔值,表示当前循环是不是最后一次循环。
forloop.parentloop:本层循环的外层循环(父循环)。
例如:
views.py:
def test_for(request):
# 定义列表变量
v_list = ['程序员', '产品经理', '产品销售', '架构师','老板','员工']
return render(request,'test_for.html',{'vlist':v_list})
html:
{% for name in vlist %}
<!-- 判断循环的第一条记录-->
{% if forloop.first %}
第一条记录:{{ name }}
<hr>
{% endif %}
<!-- forloop.counter 用法例子-->
从1开始计数:{{ forloop.counter }}--{{ name }}
<br>
<!-- forloop.counter0用法例子-->
从0开始计数:{{ forloop.counter0 }}--{{ name }}
<br>
<!-- forloop. revcounter 用法例子-->
反向计数:{{forloop.revcounter }}--{{ name }}
<!—-显示分隔线-->
<hr>
<!--#判断循环的最后一条记录-- >
{% if forloop.last %}
最后一条记录:{{ name }}
<!—-显示分隔线-->
<hr>
{% endif %}
{% endfor%}
输出结果:
第一条记录:程序员
________________________________________
从1开始计数:1--程序员
从0开始计数:0--程序员
反向计数:6--程序员
________________________________________
从1开始计数:2--产品经理
从0开始计数:1--产品经理
反向计数:5--产品经理
________________________________________
……
从1开始计数:6--员工
从0开始计数:5--员工
反向计数:1--员工
________________________________________
最后一条记录:员工
(4)模板标签with,主要用于给一个变量起别名,多用于复杂的变量,以下代码用到的vlist变量是上面views.py中test_for()视图函数传入test_for.html的变量。
{% with vlist.0 as firstname %}
第一个人员是:{{ firstname }}
{% endwith %}
1.2.2.自定义标签:
(1)在应用程序目录下新建一个文件夹templatetags(必须使用这个名字),在其下建立一个文件custom_tags.py (文件名可以任意起)
(2)编写自定义标签代码
# 导入 template 这个模块
from django import template
# 导入用到的数据模型,由于models文件存放在本文件的上一级目录,所以在models前加上..
from ..models import Blog, Category, Tag
# 导入聚合模块相关函数
from django.db.models.aggregates import Count
# 实例化了一个 template.Library 类,是固定写法
register = template.Library()
# 将函数装饰为 register.simple_tag
# 这样就可以在模板文件中使用 {% get_categories %} 调用这个函数
@register.simple_tag
def get_categories():
# 通过Django分类聚合函数统计每个分类中的文章的数量,并过滤掉没有文章的分类
return Category.objects.annotate(num_blogs=Count('blog')).filter(num_blogs__gt=0)
(3)在html引用前,先导入文件
<!-- 导入自定义模板标签 -->
{% load custom_tags %}
<div>
<!-- 调用自定义标签文件custom_tags中定义的get_categories()函数,显示每个类中的文章篇数 -->
{% get_categories as category_list %}
{% for category in category_list %}
<ol class="list-unstyled mb-0">
<li><a href="#">{{ category.name }}
<!-- 显示每个类中的文章篇数-->
<span class="post-count">({{ category.num_blogs }})</span>
</a></li>
</ol>
{% empty %}
<span>暂无分类</span>
{% endfor %}
</div>
1.3.过滤器
过滤器转换变量和标签参数的值。
{{ django|title }}{{ my_date|date:"Y-m-d" }}
1.4.注释Comments
单行注释:
{# this won't be rendered #}
多行注释:
{% comment %}
这是一个多行注释
这是第二行
这是第三行
{% endcomment %}
2.母版和继承
母版增加了块(block),这个块就是继承页面要替换的地方,以上代码中的{% block main %}…{%endblock %}就是需要在继承页面中替换的部分。
页面继承母版,文件开头需{% extends 'base.html' %},页面的样式就会与母版相似,继承页面HTML文件相关的代码必须写在block块中,不能写在外面,只能把代码写在{% block main %}…{% endblock %}之间,而且写在块中的代码才显示与母版不一样的内容,其他部分与母版一样。
3.组件
就是把HTML文件中一些相对固定的部分分离出来,存放到不同的HTML文件中,这些文件可以被模板文件引用到相应位置。
引入组件通过{% include 'xxx.html' %}引入页面