Django模板(template)
序言
django使用jinja2 为模板引擎,用两个大括号括起来的文字{{ var }} 成为变量,被大括号和百分号包围的文本 {% if ordered_warranty %} 是模板标签。在django模板中遍历复杂数据结构的关键是字符 '.' 。
# 注释方法: {# 这是注释 #} # 多行注释: {% comment %} ..... {% endcomment %}
1. 普通变量
# 普通变量 {{ var }} # 调用数组元素:(用圆点加下标) list = [1,2,3] {{ list.0 }} # 表示列表的下标为0的元素,即第一个元素 {{ list.1 }} {{ list.2 }} # 调用字典元素:(用圆点加键值) dict = {"k1":"v1","k2":"v2"} {{ dict.k1 }} # 表示字典的k1的键值 {{ dict.k2 }}
2. if 语句
# 在结构体内引用变量,不需要再加双大括号 # {% if %} 标签接受and,or,not关键字对多个变量做判断,但不要同时使用and和or,因为逻辑上可能模糊,not 为取反 # 不存在 {% elif %} 标签,如果想用,请使用嵌套的 {% if %}标签来达到效果 # 一定要用{% endif %}关闭每一个 {% if %}标签 {% if 判断 %} ... {% else %} ... {% endif %} # 在python和django模板系统中,以下对象相当于布尔值的False * 空列表 * 空元组 * 空字典 * 空字符串 * 零值(0) * 特殊对象None * 对象False 除以上几点外的所有都视为True(真)
3. for 循环
{% for i in data %}
......
{% endfor %}
# 在执行循环前先检测列表的大小是一个通常的做法,当列表为空时输出一些特别的提示
{% if athlete_list %}
{% for athlete in athlete_list %}
<p>{{ athlete.name }}</p>
{% endfor %}
{% else %}
<p>There are no athletes. Only computer programmers.</p>
{% endif %}
# for标签支持一个可选的{% empty %} 分支,通过它我们可以定义当列表为空时输出的内容,效果和上面的if标签判断一样的效果
{% for athlete in athlete_list %}
<p>{{ athlete.name }}</p>
{% empty %}
<p>There are no athletes. Only computer programmers.</p>
{% endfor %}
# django 不支持退出循环操作,也不支持continue语句
django 内置了特殊的用于for循环的变量:
forloop.counter # 总是一个表示当前循环的执行次数的整数计数器,这个计数器从1开始,所以在第一次循环时,forloop.counter将会被设置为1
forloop.counter0 # 类似于forloop.counter,但他是从0开始计数的。
forloop.first # 一个布尔值,如果该迭代是第一次执行,那么它将被设置为 True
forloop.last # 一个布尔值,在最后一次执行循环时被设置为True,一个常见的用法是在一系列的链接之间放置管道符(|)
{% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}
产生的结果: link1 | link2 | link3
4. 比较方法
# ifequal 标签 {% ifequal var1 var2 %} <h1>Welcome</h1> {% else %} <h1>bye</h1> {% endifequal %} # ifequal 标签只支持字符串,数字和小数,其他一律不支持
5. 内置函数(方法)
# 内置函数,通过管道符'|' 将管道符前面的参数传递给后面的函数,显示执行结果 示例: {{ "AAA"|lower }} # 将AAA变成小写 {{ 'bbb'|first|upper }} # 将字符串的第一个字符变成大小 {{ item.event_start|date:"Y-m-d H:i:s"}} # 时间转换 {{ bio|truncatewords:"30"}} # 只显示前30个字符 {{ item|divisibleby:"2" }} # 判断当前循环次数是否能被2整除
6. 自定义函数(方法)
自定义方法分为两类:fillter 和 simple_tag。
创建自定义方法的步骤:
- 第一步,在app中创建一个名为 templatetags的目录,注意名字不可修改,固定格式
- 第二步,在templatetags中创建 mytags.py 文件
- 第三步, 编写py文件,文件内容如下
- 第四步,在settings.py 中注册 templatetags目录所在的app
- 第五步,在模板开头中使用:{% load mytags %}, mytags是第二步中创建的py文件名,这里是导入自定义方法的意思
# mytags.py from django import template from django.utils.safestring import mark_safe register = template.Library() # 固定写法 @register.filter def f1(value): return value + 'v587' # f1方法将输入的字符串结尾添加v587后返回 @register.simple_tag def my_simple_time(v1,v2,v3): return v1 + v2 + v3 @register.simple_tag def my_input(id,arg): result = "<input type='text' id='%s' class='%s' />" %(id,arg,) return mark_safe(result)
# 模板文件 # filter 方法使用 {{ item|f1 }} # 默认是将item当做参数传入f1方法 {{ item|f1:"abc"}} # 传递两个参数,第一个参数是item,第二个参数就是"abc" {{ item|f1:"abc,bcd"}} # 传递更多参数,只能通过字符串分隔方法 # simple_tag 方法使用 {% my_simple_time 1 2 3 %} # 方法后接空格,然后是传参,有几个就传几个 # filter和simple_tag 的区别 # filter可以当错模板语言中的if 的条件, simple_tag 则不可以 {% if item|k1 %}
7. 模板继承
{% extends "xxx.html" %}
# 在子模板开头,表示你要继承哪个基础模板(父模板)
{% block 父模板中定义的名字 %}
...
{% endblock %}
8. 重写模板
# 在基础模板(父模板)中的段落加入block标签,表示子模板将重写这段代码 在父版和子版中使用同样的: {% block 自定义名字 %} (每个子版专属代码) {% endblock %}
9. 导入模板
{% include "xxx.hmtl" %}
# 与继承模板不同的是,导入是xxx.html的完全代码,因此xxx.html中最好没有头部,title等代码,只有实际的功能代码
# 如果 include 标签指定的模板没有找到,django会有两种处理方式
1. 如果DEBUG 设置为 True,将会在django 错误信息页面看到 TemplateDoesNotExit 异常
2. 如果DEBUG 设置为 False,该标签不会引发错误信息,在标签位置不显示任何东西
注意: 模板一般放在app 下的 templates中,django会自动到这个文件夹中寻找。
Django 模板的查找机制:
Django查找模板的过程是在每个app的templates 文件中找(而不只是当前app的templates中)。各个 app 的template 形成一个文件夹列表,Django遍历这个列表,一个一个文件夹进行查找,当在某一个文件夹中找到的时候就停止,所有的文件夹都遍历后如果还没找到指定模板的时候就是 Template Not Found。这样设计的优点是一个app可以用另一个app的模板文件,缺点是可能会找错,解决办法就是在templates 中建立一个 app 同名的文件夹。
10. 一些特殊技巧
# 获取当前用户 {{ request.user }} # 登陆就显示内容,不登陆就不显示内容 {% if request.user.is_authenticated % } {{ request.user.username }},您好! {% else %} 点击登陆 {% endif %} # 获取当前网址 {{ request.path }} # 获取当前GET参数 {{ request.GET.urlencode }}

浙公网安备 33010602011771号