Djange 的模板层
1.模板语法之变量
- 在 Django 模板中遍历复杂数据结构的关键是句点字符, 语法:
1 {{var_name}}
views.py:
1 def index(request): 2 import datetime 3 s="hello" 4 l=[111,222,333] # 列表 5 dic={"name":"wqz","age":18} # 字典 6 date = datetime.date(1993, 5, 2) # 日期对象 7 8 class Person(object): 9 def __init__(self,name): 10 self.name=name 11 12 person_yuan=Person("wqz") # 自定义类对象 13 person_egon=Person("yjw") 14 person_alex=Person("www") 15 16 person_list=[person_yuan,person_egon,person_alex] 17 18 19 return render(request,"index.html",{"l":l,"dic":dic,"date":date,"person_list":person_list})
template:
1 <h4>{{s}}</h4> 2 <h4>列表:{{ l.0 }}</h4> 3 <h4>列表:{{ l.2 }}</h4> 4 <h4>字典:{{ dic.name }}</h4> 5 <h4>日期:{{ date.year }}</h4> 6 <h4>类对象列表:{{ person_list.0.name }}</h4>
2.模板之过滤器
- 语法
1 {{obj|filter__name:param}}
- default:
如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:
1 {{ value|default:"nothing" }}
- length:
返回值的长度。它对字符串和列表都起作用。例如:
1 {{ value|default:"nothing" }}
- filesizeformat:
将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB'
, '4.1 MB'
, '102 bytes'
, 等等)。例如:
1 {{ value|filesizeformat }}
- date:
如果 value=datetime.datetime.now()
1 {{ value|date:"Y-m-d" }}
- slice:
如果 value="hello world"
1 {{ value|slice:"2:-1" }}
- truncatechars:
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
参数:要截断的字符数
1 {{ value|truncatechars:9 }}
- safe:
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:
1 value="<a href="">点击</a>" 2 {{ value|safe}}
3.模板之标签
标签看起来像是这样的: {% tag %}
。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。一些标签需要开始和结束标签 (例如{% tag %} ...
标签 内容 ... {% endtag %})。
- for标签
1 遍历每一个元素: 2 3 {% for person in person_list %} 4 <p>{{ person.name }}</p> 5 {% endfor %} 6 可以利用{% for obj in list reversed %}反向完成循环。 7 8 遍历一个字典: 9 10 {% for key,val in dic.items %} 11 <p>{{ key }}:{{ val }}</p> 12 {% endfor %} 13 注:循环序号可以通过{{forloop}}显示 14 15 forloop.counter The current iteration of the loop (1-indexed) 16 forloop.counter0 The current iteration of the loop (0-indexed) 17 forloop.revcounter The number of iterations from the end of the loop (1-indexed) 18 forloop.revcounter0 The number of iterations from the end of the loop (0-indexed) 19 forloop.first True if this is the first time through the loop 20 forloop.last True if this is the last time through the loop
- if 标签
{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
1 {% if num > 100 or num < 0 %} 2 <p>无效</p> 3 {% elif num > 80 and num < 100 %} 4 <p>优秀</p> 5 {% else %} 6 <p>凑活吧</p> 7 {% endif %}
- with
使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的
1 {% with total=business.employees.count %} 2 {{ total }} employee{{ total|pluralize }} 3 {% endwith %}
4.模板继承(extend)
Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。
通过从下面这个例子开始,可以容易的理解模版继承:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <link rel="stylesheet" href="style.css" /> 5 <title>{% block title %}My amazing site{%/span> endblock %}</title> 6 </head> 7 8 <body> 9 <div id="sidebar"> 10 {% block sidebar %} 11 <ul> 12 <li><a href="/">Home</a></li> 13 <li><a href="/blog/">Blog</a></li> 14 </ul> 15 {% endblock %} 16 </div> 17 18 <div id="content"> 19 {% block content %}{% endblock %} 20 </div> 21 </body> 22 </html>
这个模版,我们把它叫作 base.html
, 它定义了一个可以用于两列排版页面的简单HTML骨架。“子模版”的工作是用它们的内容填充空的blocks。
在这个例子中, block
标签定义了三个可以被子模版内容填充的block。 block
告诉模版引擎: 子模版可能会覆盖掉模版中的这些位置。
子模版可能看起来是这样的:
1 {% extends "base.html" %} 2 3 {% block title %}My amazing blog{% endblock %} 4 5 {% block content %} 6 {% for entry in blog_entries %} 7 <h2>{{ entry.title }}</h2> 8 <p>{{ entry.body }}</p> 9 {% endfor %} 10 {% endblock %
extends
标签是这里的关键。它告诉模版引擎,这个模版“继承”了另一个模版。当模版系统处理这个模版时,首先,它将定位父模版——在此例中,就是“base.html”。
那时,模版引擎将注意到 base.html
中的三个 block
标签,并用子模版中的内容来替换这些block。根据 blog_entries
的值,输出可能看起来是这样的:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <link rel="stylesheet" href="style.css" /> 5 <title>My amazing blog</title> 6 </head> 7 8 <body> 9 <div id="sidebar"> 10 <ul> 11 <li><a href="/">Home</a></li> 12 <li><a href="/blog/">Blog</a></li> 13 </ul> 14 </div> 15 16 <div id="content"> 17 <h2>Entry one</h2> 18 <p>This is my first entry.</p> 19 20 <h2>Entry two</h2> 21 <p>This is my second entry.</p> 22 </div> 23 </body> 24 </html>
5 自定义标签和过滤器
- 1 在settings中的INSTALLED_APPS配置当前app,不然django无法找到simple_tag
- 2 在app中创建templatetags模块(模块名只能是templatetags)
- 3 创建.py文件,如 my_tags.py
1 from django import template 2 from django.utils.safestring import mark_safe 3 4 register = template.Library() #register的名字是固定的,不可改变 5 6 7 @register.filter 8 def filter_multi(v1,v2): 9 return v1 * v2 10 <br> 11 @register.simple_tag 12 def simple_tag_multi(v1,v2): 13 return v1 * v2 14 <br> 15 @register.simple_tag 16 def my_input(id,arg): 17 result = "<input type='text' id='%s' class='%s' />" %(id,arg,) 18 return mark_safe(result)
- 4 在使用自定义simple_tag 和filter的html文件中导入之前创建的my_tags.py
{% load my_tags %}
- 5 使用simple_tag和filter
1 -------------------------------.html 2 {% load xxx %} 3 4 # num=12 5 {{ num|filter_multi:2 }} #24 6 7 {{ num|filter_multi:"[22,333,4444]" }} 8 9 {% simple_tag_multi 2 5 %} 参数不限,但不能放在if for语句中 10 {% simple_tag_multi num 5 %}
- 注意 filter可以用在if等语句后,simple_tag不可以