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 }}

 

posted @ 2018-03-05 22:26  Auvღ  阅读(1202)  评论(0)    收藏  举报