前面的章节咱们看到如何在视图中返回HTML,可是HTML是硬编码在Python代码中的
这会致使几个问题:
1,显然,任何页面的改动会牵扯到Python代码的改动
网站的设计改动会比Python代码改动更频繁,因此若是咱们将二者分离开会更方便
2,其次,写后台Python代码与设计HTML是不一样的工做,更专业的Web开发应该将二者分开
页面设计者和HTML/CSS程序员不该该编辑Python代码,他们应该与HTML打交道
3,程序员写Python代码同时页面设计者写HTML模板会更高效,而不是一我的等待另外一我的编辑一样的文件
所以,使用Django的模板系统分离设计和Python代码会更干净更易维护css
基于这些缘由,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 咱们可使用 Django的 模板系统 (Template System)来实现这种模式,html
1.1 模板之标签python
标签看起来像是这样的: {% tag %}
。标签比变量更加复杂:一些在输出中建立文本,一些经过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。程序员
一些标签须要开始和结束标签 (例如{% tag %} ...
标签 内容 ... {% endtag %})数据库
for标签django
遍历每个元素:缓存
{% for person in person_list %} <p>{{ person.name }}</p> {% endfor %}
遍历一个字典:app
{% for key,val in dic.items %} <p>{{ key }}:{{ val }}</p> {% endfor %}
注:循环序号能够经过{{forloop}}显示 ide
{% if %}会对一个变量求值,若是它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。oop
{% if num > 100 or num < 0 %} <p>无效</p> {% elif num > 80 and num < 100 %} <p>优秀</p> {% else %} <p>凑活吧</p> {% endif %}
使用一个简单地名字缓存一个复杂的变量,当你须要使用一个“昂贵的”方法(好比访问数据库)不少次的时候是很是有用的
例如:
{% with total=business.employees.count %} {{ total }} employee{{ total|pluralize }} {% endwith %}
一、在settings中的INSTALLED_APPS配置当前app,否则django没法找到自定义的simple_tag.
二、在app中建立templatetags模块(模块名只能是templatetags)
三、建立任意 .py 文件,如:my_tags.py
from django import template from django.utils.safestring import mark_safe register = template.Library() #register的名字是固定的,不可改变 @register.filter def filter_multi(v1,v2): return v1 * v2 <br> @register.simple_tag def simple_tag_multi(v1,v2): return v1 * v2 <br> @register.simple_tag def my_input(id,arg): result = "<input type='text' id='%s' class='%s' />" %(id,arg,) return mark_safe(result)
四、在使用自定义simple_tag和filter的html文件中导入以前建立的 my_tags.py
1
|
{
%
load my_tags % }
|
五、使用simple_tag和filter(如何调用)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
.html
{
%
load xxx
%
}
# num=12
{{ num|filter_multi:
2
}}
#24
{{ num|filter_multi:
"[22,333,4444]"
}}
{
%
simple_tag_multi
2
5
%
} 参数不限,但不能放在
if
for
语句中
{
%
simple_tag_multi num
5
%
}
注意:filter能够用在if等语句后,simple_tag不能够
{% if num|filter_multi:30 > 100 %} {{ num|filter_multi:30 }} {% endif %}
Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可让您建立一个基本的“骨架”模版,它包含您站点中的所有元素,而且能够定义可以被子模版覆盖的 blocks 。
经过从下面这个例子开始,能够容易的理解模版继承:
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="style.css" /> <title>{% block title %}My amazing site{%/span> endblock %}</title> </head> <body> <div id="sidebar"> {% block sidebar %} <ul> <li><a href="/">Home</a></li> <li><a href="/blog/">Blog</a></li> </ul> {% endblock %} </div> <div id="content"> {% block content %}{% endblock %} </div> </body> </html>
这个模版,咱们把它叫做 base.html
, 它定义了一个能够用于两列排版页面的简单HTML骨架。“子模版”的工做是用它们的内容填充空的blocks。
在这个例子中, block
标签订义了三个能够被子模版内容填充的block。 block
告诉模版引擎: 子模版可能会覆盖掉模版中的这些位置。
子模版可能看起来是这样的:
{% extends "base.html" %} {% block title %}My amazing blog{% endblock %} {% block content %} {% for entry in blog_entries %} <h2>{{ entry.title }}</h2> <p>{{ entry.body }}</p> {% endfor %} {% endblock %}
extends
标签是这里的关键。它告诉模版引擎,这个模版“继承”了另外一个模版。当模版系统处理这个模版时,首先,它将定位父模版——在此例中,就是“base.html”。
那时,模版引擎将注意到 base.html
中的三个 block
标签,并用子模版中的内容来替换这些block。根据 blog_entries
的值,输出可能看起来是这样的:
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="style.css" /> <title>My amazing blog</title> </head> <body> <div id="sidebar"> <ul> <li><a href="/">Home</a></li> <li><a href="/blog/">Blog</a></li> </ul> </div> <div id="content"> <h2>Entry one</h2> <p>This is my first entry.</p> <h2>Entry two</h2> <p>This is my second entry.</p> </div> </body> </html>
请注意,子模版并无定义 sidebar
block,因此系统使用了父模版中的值。父模版的 {% block %}
标签中的内容老是被用做备选内容(fallback)。
这种方式使代码获得最大程度的复用,而且使得添加内容到共享的内容区域更加简单,例如,部分范围内的导航。
这里是使用继承的一些提示:
若是你在模版中使用 {% extends %}
标签,它必须是模版中的第一个标签。其余的任何状况下,模版继承都将没法工做。
在base模版中设置越多的 {% block %}
标签越好。请记住,子模版没必要定义所有父模版中的blocks,因此,你能够在大多数blocks中填充合理的默认内容,而后,只定义你须要的那一个。多一点钩子总比少一点好。
若是你发现你本身在大量的模版中复制内容,那可能意味着你应该把内容移动到父模版中的一个 {% block %}
中。
If you need to get the content of the block from the parent template, the {{ block.super }}
variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using {{ block.super }}
will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.
为了更好的可读性,你也能够给你的 {% endblock %}
标签一个 名字 。例如:
1
2
3
|
{
%
block content % }
...
{
%
endblock content % }
|
在大型模版中,这个方法帮你清楚的看到哪个 {% block %}
标签被关闭了。
最后,请注意您并不能在一个模版中定义多个相同名字的 block
标签。这个限制的存在是由于block标签的做用是“双向”的。这个意思是,block标签不只提供了一个坑去填,它还在 _父模版_中定义了填坑的内容。若是在一个模版中有两个名字同样的 block
标签,模版的父模版将不知道使用哪一个block的内容。