- 模板层介绍
- 模板语言变量
- 模板语言过滤器
- 模板语言标签
- 自定义标签和过滤器
- 模板导入
- 模板继承
- 静态文件配置
- 使用get_static_prefix
- inclusion_tag
-曾老湿, 江湖人称曾老大。
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
模板层介绍
模版简介 |
---|
你可能已经注意到我们在例子视图中返回文本的方式有点特别。 也就是说,HTML被直接硬编码在 Python代码之中。
代码语言:javascript复制def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不是一个好主意。 让我们来看一下为什么:
1.对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。
2.Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。
模板语言变量
视图设置变量,前端调用 |
---|
## 路由
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
]
代码语言:javascript复制<!-- html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>模板语言-变量</h1>
<hr>
<!-- 调用变量 -->
{{ name }}
</body>
</html>
代码语言:javascript复制## 视图
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
def index(request):
name='曾老湿'
return render(request,'index.html',{'name':name})

代码语言:javascript复制from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
def index(request):
name='曾老湿'
## locals() 会把该视图函数内的所有变量,都传到模板
return render(request,'index.html',locals())

代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>模板语言-变量</h1>
<hr>
{{ name }}
<hr>
{{ age }}
</body>
</html>
代码语言:javascript复制from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
def index(request):
name='曾老湿'
age=18
## locals() 会把该视图函数内的所有变量,都传到模板
return render(request,'index.html',locals())

添加所有类型 |
---|
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def index(request):
name = '曾老湿'
age = 18
li = [1, 2, 3, 4, 'zls']
dic = {'name': '苍井空', 'age': 18}
tup = ('abc', 'def', 'ghi')
def func():
print('zls')
return '波多野结衣'
## locals() 会把该视图函数内的所有变量,都传到模板
return render(request, 'index.html', locals())
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>模板语言-变量</h1>
<hr>
字符串:{{ name }}
<hr>
整型:{{ age }}
<hr>
列表:{{ li }}
<hr>
字典:{{ dic }}
<hr>
元组:{{ tup }}
<hr>
函数:{{ func }}
<hr>
</body>
</html>

深度查询 |
---|
和ansible以及saltstack一样。如果数据是一个列表或者字典,我们想查询其中一个数据,那就使用句点符来获取数据。
例如:
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>模板语言-变量</h1>
<hr>
字符串:{{ name }}
<hr>
整型:{{ age }}
<hr>
列表:{{ li.0 }}
<hr>
字典:{{ dic.name }}
<hr>
元组:{{ tup.1 }}
<hr>
函数:{{ func }}
<hr>
</body>
</html>

类和对象
代码语言:javascript复制from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def index(request):
name = '曾老湿'
age = 18
li = [1, 2, 3, 4, 'zls']
dic = {'name': '苍井空', 'age': 18}
tup = ('abc', 'def', 'ghi')
def func():
print('zls')
return '波多野结衣'
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def get_name(self):
return self.name
@classmethod
def cls_test(cls):
return 'cls'
@staticmethod
def static_test():
return 'static'
# 模板里不支持带参数
def get_name_cs(self, ttt):
return self.name
zls = Person('zls', 18)
cls = Person('cls', 18)
person_list = [zls, cls]
person_dic = {'zls': zls}
## locals() 会把该视图函数内的所有变量,都传到模板
return render(request, 'index.html', locals())
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>模板语言之变量</h1>
<p>字符串:{{ name }}</p>
<p>数字:{{ age }}</p>
<p>列表:{{ li }}</p>
<p>元祖:{{ tup }}</p>
<p>字典:{{ dic }}</p>
{#只写函数名:相当于函数名(),执行该函数#}
<p>函数:{{ test }}</p>
{#对象内存地址#}
<p>对象:{{ zls }}</p>
<p>列表套对象:{{ person_list }}</p>
<p>字典套对象:{{ person_dic }}</p>
<hr>
<h1>深度查询</h1>
<p>列表第0个值:{{ ll.0 }}</p>
<p>列表第3个值:{{ ll.3 }}</p>
<p>字典取值:{{ dic.name }}</p>
<p>字典取列表值:{{ dic.ll }}</p>
{#再继续取值,继续点#}
<p>对象取数据属性:{{ zls.name }}</p>
<p>对象取绑定给对象的函数属性:{{ zls.get_name }}</p>
<p>对象取绑定给类的函数属性:{{ zls.cls_test }}</p>
<p>对象取静态方法:{{ zls.static_test }}</p>
<p>把对象列表中cls年龄取出来:{{ person_list.1.age }}</p>
{#拓展:不能调有参数的方法#}
<p>字符串的方法:{{ name.upper }}</p>
</body>
</html>

模板语言过滤器
语法 |
---|
{{obj|filter__name:param}} 变量名字|过滤器名称:变量
过滤器使用 |
---|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>模板语言之过滤器</h1>
<p>统计字符串长度:{{ name|length }}</p>
<p>统计字列表长度:{{ li|length }}</p>
<p>过滤器默认值:{{ li|default:'没有值'}}</p>
<p>过滤器默认值:{{ li2|default:'没有值'}}</p>
<p>过滤器filesizeformat---1:{{ 1024|filesizeformat}}</p>
<p>过滤器filesizeformat---2:{{ file_size|filesizeformat}}</p>
<p>过滤器不用date:{{ ctim}}</p>
<p>过滤器使用date:{{ ctim|date:'Y-m-d'}}</p>
{#支持步长#}
<p>过滤器slice切列表:{{ li|slice:'2:-1'}}</p>
<p>过滤器slice切字符串:{{ name|slice:'0:-1'}}</p>
{#截断字符:使用场景,博客的内容摘要#}
<p>过滤器truncatechars:{{ 'ssssszzzzccccc'|truncatechars:5 }}</p>
{#截断单词:使用场景,博客的内容摘要#}
<p>过滤器truncat:{{ '你 hao hello 我 哎呀 fuck'|truncatewords:5 }}</p>
{#重中之重#}
<p>过滤器不用safe:{{ h1 }}</p>
<p>过滤器使用safe:{{ h1|safe }}</p>
</body>
</html>
代码语言:javascript复制from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def index(request):
name = '曾老湿'
age = 18
li = [1, 2, 3, 4, 'zls']
dic = {'name': '苍井空', 'age': 18}
tup = ('abc', 'def', 'ghi')
def func():
print('zls')
return '波多野结衣'
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def get_name(self):
return self.name
@classmethod
def cls_test(cls):
return 'cls'
@staticmethod
def static_test():
return 'static'
# 模板里不支持带参数
def get_name_cs(self, ttt):
return self.name
zls = Person('zls', 18)
cls = Person('cls', 18)
person_list = [zls, cls]
person_dic = {'zls': zls}
file_size=1024
import datetime
ctim=datetime.datetime.now()
h1='<h1>你好</h1>'
## locals() 会把该视图函数内的所有变量,都传到模板
return render(request, 'index.html', locals())

其它过滤器(了解) |
---|
过滤器 | 描述 | 示例 |
---|---|---|
upper | 以大写方式输出 | {{ user.name | upper }} |
add | 给value加上一个数值 | {{ user.age | add:”5” }} |
addslashes | 单引号加上转义号 | |
capfirst | 第一个字母大写 | {{ ‘good’| capfirst }} 返回”Good” |
center | 输出指定长度的字符串,把变量居中 | {{ “abcd”| center:”50” }} |
cut | 删除指定字符串 | {{ “You are not a Englishman” | cut:”not” }} |
date | 格式化日期 | |
default | 如果值不存在,则使用默认值代替 | {{ value | default:”(N/A)” }} |
default_if_none | 如果值为None, 则使用默认值代替 | |
dictsort | 按某字段排序,变量必须是一个dictionary | {% for moment in moments | dictsort:”id” %} |
dictsortreversed | 按某字段倒序排序,变量必须是dictionary | |
divisibleby | 判断是否可以被数字整除 | {{ 224 | divisibleby:2 }} 返回 True |
escape | 按HTML转义,比如将”<”转换为”<” | |
filesizeformat | 增加数字的可读性,转换结果为13KB,89MB,3Bytes等 | {{ 1024 | filesizeformat }} 返回 1.0KB |
first | 返回列表的第1个元素,变量必须是一个列表 | |
floatformat | 转换为指定精度的小数,默认保留1位小数 | {{ 3.1415926 | floatformat:3 }} 返回 3.142 四舍五入 |
get_digit | 从个位数开始截取指定位置的数字 | {{ 123456 | get_digit:’1’}} |
join | 用指定分隔符连接列表 | {{ [‘abc’,’45’] | join:’’ }} 返回 abc45 |
length | 返回列表中元素的个数或字符串长度 | |
length_is | 检查列表,字符串长度是否符合指定的值 | {{ ‘hello’| length_is:’3’ }} |
linebreaks | 用 或标签包裹变量 | {{ “HinnDavid”|linebreaks }} 返回 Hi David |
linebreaksbr | 用标签代替换行符 | |
linenumbers | 为变量中的每一行加上行号 | |
ljust | 输出指定长度的字符串,变量左对齐 | {{‘ab’|ljust:5}}返回 ‘ab ’ |
lower | 字符串变小写 | |
make_list | 将字符串转换为列表 | |
pluralize | 根据数字确定是否输出英文复数符号 | |
random | 返回列表的随机一项 | |
removetags | 删除字符串中指定的HTML标记 | {{value | removetags: “h1 h2”}} |
rjust | 输出指定长度的字符串,变量右对齐 | |
slice | 切片操作, 返回列表 | {{[3,9,1] | slice:’:2’}} 返回 [3,9] {{ 'asdikfjhihgie' | slice:':5' }} 返回 ‘asdik’ |
slugify | 在字符串中留下减号和下划线,其它符号删除,空格用减号替换 | {{ '5-2=3and5 2=3' | slugify }} 返回 5-23and5-23 |
stringformat | 字符串格式化,语法同python | |
time | 返回日期的时间部分 | |
timesince | 以“到现在为止过了多长时间”显示时间变量 | 结果可能为 45days, 3 hours |
timeuntil | 以“从现在开始到时间变量”还有多长时间显示时间变量 | |
title | 每个单词首字母大写 | |
truncatewords | 将字符串转换为省略表达方式 | {{ 'This is a pen' | truncatewords:2 }}返回This is ... |
truncatewords_html | 同上,但保留其中的HTML标签 | {{ '<p>This is a pen</p>' | truncatewords:2 }}返回<p>This is ...</p> |
urlencode | 将字符串中的特殊字符转换为url兼容表达方式 | {{ ‘http://www.aaa.com/foo?a=b&b=c’ | urlencode}} |
urlize | 将变量字符串中的url由纯文本变为链接 | |
wordcount | 返回变量字符串中的单词数 | |
yesno | 将布尔变量转换为字符串yes, no 或maybe | {{ True | yesno }}{{ False | yesno }}{{ None | yesno }}返回yesnomaybe |
模板语言标签
标签介绍 |
---|
标签看起来像是这样的: {% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。一些标签需要开始和结束标签 (例如{% tag %} ...标签 内容 ... {% endtag %})。
标签使用-循环 |
---|
forloop.counter The current iteration of the loop (1-indexed) 当前循环的索引值(从1开始)
forloop.counter0 The current iteration of the loop (0-indexed) 当前循环的索引值(从0开始)
forloop.revcounter The number of iterations from the end of the loop (1-indexed) 当前循环的倒序索引值(从1开始)
forloop.revcounter0 The number of iterations from the end of the loop (0-indexed) 当前循环的倒序索引值(从0开始)
forloop.first True if this is the first time through the loop 当前循环是不是第一次循环(布尔值)
forloop.last True if this is the last time through the loop 当前循环是不是最后一次循环(布尔值)forloop.parentloop 本层循环的外层循环
循环列表
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>模板语言之标签</h1>
{% for foo in li %}
<p>{{ foo }}</p>
{% endfor %}
<hr>
{% for foo in li %}
{{ forloop }}
<p>{{ forloop.first }} === {{ forloop.revcounter }} === {{ foo }}</p>
{% endfor %}
<hr>
{% for foo in li %}
{% for i in person_list %}
{# 取出外层是第几次循环 #}
{{ forloop.parentloop.counter }}
<p>{{ forloop.first }} === {{ forloop.revcounter }} === {{ foo }}</p>
{% endfor %}
{% endfor %}
<hr>
{# 循环的对象如果是空,则返回empty的内容 #}
{% for foo in li1 %}
<p>{{ foo }}</p>
{% empty %}
傻逼了
{% endfor %}
</body>
</html>
代码语言:javascript复制from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def index(request):
name = '曾老湿'
age = 18
li = [1, 2, 3, 4, 'zls']
dic = {'name': '苍井空', 'age': 18}
tup = ('abc', 'def', 'ghi')
def func():
print('zls')
return '波多野结衣'
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def get_name(self):
return self.name
@classmethod
def cls_test(cls):
return 'cls'
@staticmethod
def static_test():
return 'static'
# 模板里不支持带参数
def get_name_cs(self, ttt):
return self.name
zls = Person('zls', 18)
cls = Person('cls', 18)
person_list = [zls, cls]
person_dic = {'zls': zls}
file_size=1024
import datetime
ctim=datetime.datetime.now()
h1='<h1>你好</h1>'
## locals() 会把该视图函数内的所有变量,都传到模板
return render(request, 'index.html', locals())


循环字典
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>模板语言之标签</h1>
{#只循环字典,只能取到key#}
{% for k in dic %}
<p>{{ k }}</p>
{% endfor %}
<hr>
{#循环value#}
{% for v in dic.values %}
<p>{{ v }}</p>
{% endfor %}
<hr>
{#循环key和value#}
{% for k,v in dic.items %}
<p>{{ k }}:{{ v }}</p>
{% endfor %}
</body>
</html>
代码语言:javascript复制from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def index(request):
name = '曾老湿'
age = 18
li = [1, 2, 3, 4, 'zls']
dic = {'name': '苍井空', 'age': 18}
tup = ('abc', 'def', 'ghi')
def func():
print('zls')
return '波多野结衣'
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def get_name(self):
return self.name
@classmethod
def cls_test(cls):
return 'cls'
@staticmethod
def static_test():
return 'static'
# 模板里不支持带参数
def get_name_cs(self, ttt):
return self.name
zls = Person('zls', 18)
cls = Person('cls', 18)
person_list = [zls, cls]
person_dic = {'zls': zls}
file_size=1024
import datetime
ctim=datetime.datetime.now()
h1='<h1>你好</h1>'
## locals() 会把该视图函数内的所有变量,都传到模板
return render(request, 'index.html', locals())

标签使用-判断 |
---|
{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>模板语言之标签</h1>
<hr>
{% if user %}
<a href="">退出</a>
{% else %}
<a href="">登录</a>
<a href="">注册</a>
{% endif %}
<hr>
<h2>for循环套if</h2>
{% for foo in li %}
{% if forloop.first %}
<p>第一次</p>
{% elif forloop.last %}
<p>最后一次</p>
{% else %}
<p>{{ foo }}</p>
{% endif %}
{% endfor %}
</body>
</html>

标签使用-别名 |
---|
使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的。或者字典和列表的深度比较深例如li.lnmp.framework.web.package
我们可以简化aspackages
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>模板语言之标签</h1>
<hr>
{% with name as qqq %}
<p>{{ qqq }}</p>
{% endwith %}
标签使用-csrf_token |
---|
这个标签用于跨站请求伪造保护
代码语言:javascript复制{% csrf_token%}
自定义标签和过滤器
1.在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag. 2.在app中创建templatetags模块(模块名只能是templatetags) 3.创建任意 .py 文件,如:my_tags.py
代码语言:javascript复制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)
4.在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
代码语言:javascript复制{% load my_tags %}
5.使用simple_tag和filter(如何调用)
代码语言:javascript复制-------------------------------.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不可以
代码语言:javascript复制{% if num|filter_multi:30 > 100 %}
{{ num|filter_multi:30 }}
{% endif %}
模板导入
模板导入介绍 |
---|
需求,之前写了一个组件,index.html中用,login.html页面也需要使用。所以我们需要写一个模板,然后导入。
创建项目 |
---|
from django.shortcuts import render
# Create your views here.
def template_test(request):
return render(request,'template_test.html')
代码语言:javascript复制from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^template/', views.template_test),
]
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板导入</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<style>
.head {
height: 60px;
background: #1b6d85;
margin-bottom: 10px;
}
body{
background: #0f0f0f;
}
</style>
</head>
<body>
<div class="head"></div>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">欧美</h3>
</div>
<div class="panel-body">
金八天国
</div>
<div class="panel-footer">点击查看</div>
</div>
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">日韩</h3>
</div>
<div class="panel-body">
东京热
</div>
<div class="panel-footer">点击查看</div>
</div>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">大型**网站</h3>
</div>
<div class="panel-body">
草榴社区
</div>
<div class="panel-footer">点击付费</div>
</div>
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">egon</h3>
</div>
<div class="panel-body">
重金求子
</div>
<div class="panel-footer">点击查看详情</div>
</div>
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">图区</h3>
</div>
<div class="panel-body">
丝袜美腿
</div>
<div class="panel-footer">点击查看</div>
</div>
</div>
<div class="col-md-9"></div>
</div>
</div>
</body>
</html>

左边的导航区域,我觉得很好看,其他页面也需要用到,我们就需要给它导入{% include 'left.html' %}
。
left.html
代码语言:javascript复制<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">欧美</h3>
</div>
<div class="panel-body">
金八天国
</div>
<div class="panel-footer">点击查看</div>
</div>
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">日韩</h3>
</div>
<div class="panel-body">
东京热
</div>
<div class="panel-footer">点击查看</div>
</div>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">大型**网站</h3>
</div>
<div class="panel-body">
草榴社区
</div>
<div class="panel-footer">点击付费</div>
</div>
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">egon</h3>
</div>
<div class="panel-body">
重金求子
</div>
<div class="panel-footer">点击查看详情</div>
</div>
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">图区</h3>
</div>
<div class="panel-body">
丝袜美腿
</div>
<div class="panel-footer">点击查看</div>
</div>
template_test.html
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板导入</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<style>
.head {
height: 60px;
background: #1b6d85;
margin-bottom: 10px;
}
body{
background: #0f0f0f;
}
</style>
</head>
<body>
<div class="head"></div>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<!-- 导入模板 -->
{% include 'left.html' %}
</div>
<div class="col-md-9"></div>
</div>
</div>
</body>
</html>
模板继承
Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。
创建项目 |
---|
views.py
代码语言:javascript复制from django.shortcuts import render
# Create your views here.
def template_test(request):
return render(request,'template_test.html')
def template1(request):
return render(request,'template1.html')
urls.py
代码语言:javascript复制from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^template/', views.template_test),
url(r'^template1/', views.template1),
]
template1.html
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板继承</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<style>
.head {
height: 60px;
background: #1b6d85;
margin-bottom: 10px;
}
body{
background: #0f0f0f;
}
p{
color: white;
}
</style>
</head>
<body>
<div class="head"></div>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
{% include 'left.html' %}
</div>
<div class="col-md-9">
<p>这里是9的区域</p>
<p>这里是9的区域</p>
<p>这里是9的区域</p>
<p>这里是9的区域</p>
<p>这里是9的区域</p>
<p>这里是9的区域</p>
<p>这里是9的区域</p>
<p>这里是9的区域</p>
<p>这里是9的区域</p>
</div>
</div>
</div>
</body>
</html>

我现在只想让9的区域变化,其他的地方都不变,这里就需要用到模板的继承了。
第一步,我们需要定义一个 母版
,就是母体,其他网站都继承这个母体。
base.html
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板继承</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<style>
.head {
height: 60px;
background: #1b6d85;
margin-bottom: 10px;
}
body{
background: #0f0f0f;
}
p{
color: white;
}
</style>
</head>
<body>
<div class="head"></div>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
{% include 'left.html' %}
</div>
<div class="col-md-9">
{% block content %}
{% endblock %}
</div>
</div>
</div>
</body>
</html>
template1.html 继承母版
代码语言:javascript复制{% extends 'base.html' %}

template1.html 添加内容
代码语言:javascript复制{% extends 'base.html' %}
{% block content %}
<p>这是9的区域</p>
<p>这是9的区域</p>
<p>这是9的区域</p>
<p>这是9的区域</p>
<p>这是9的区域</p>
<p>这是9的区域</p>
<p>这是9的区域</p>
{% endblock %}

测试再创建一个template2.html
代码语言:javascript复制{% extends 'base.html' %}
{% block content %}
<p>这里是template2的页面</p>
<p>这里是template2的页面</p>
<p>这里是template2的页面</p>
<p>这里是template2的页面</p>
<p>这里是template2的页面</p>
<p>这里是template2的页面</p>
<p>这里是template2的页面</p>
{% endblock %}
添加路由
代码语言:javascript复制from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^template/', views.template_test),
url(r'^template1/', views.template1),
url(r'^template2/', views.template2),
]
添加视图
代码语言:javascript复制from django.shortcuts import render
# Create your views here.
def template_test(request):
return render(request,'template_test.html')
def template1(request):
return render(request,'template1.html')
def template2(request):
return render(request,'template2.html')

既显示母版内容又显示自己内容 |
---|
请注意,子模版并没有定义 sidebar block,所以系统使用了父模版中的值。父模版的 {% block %} 标签中的内容总是被用作备选内容(fallback)。
这种方式使代码得到最大程度的复用,并且使得添加内容到共享的内容区域更加简单,例如,部分范围内的导航。
这里是使用继承的一些提示:
1.如果你在模版中使用 {% extends %} 标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。
2.在base模版中设置越多的 {% block %} 标签越好。请记住,子模版不必定义全部父模版中的blocks,所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。
3.如果你发现你自己在大量的模版中复制内容,那可能意味着你应该把内容移动到父模版中的一个 {% 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.
base.html
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板继承</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<style>
.head {
height: 60px;
background: #1b6d85;
margin-bottom: 10px;
}
body{
background: #0f0f0f;
}
p{
color: white;
}
</style>
</head>
<body>
<div class="head"></div>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
{% include 'left.html' %}
</div>
<div class="col-md-9">
{% block content %}
<p>这是母版的内容</p>
<p>这是母版的内容</p>
<p>这是母版的内容</p>
<p>这是母版的内容</p>
<p>这是母版的内容</p>
<p>这是母版的内容</p>
{% endblock %}
</div>
</div>
</div>
</body>
</html>
template2.html
代码语言:javascript复制{% extends 'base.html' %}
{% block content %}
<p>这里是template2的页面</p>
<p>这里是template2的页面</p>
<p>这里是template2的页面</p>
<p>这里是template2的页面</p>
{{ block.super }}
<p>这里是template2的页面</p>
<p>这里是template2的页面</p>
<p>这里是template2的页面</p>
{% endblock %}

静态文件配置
代码语言:javascript复制{% load static %}
<img src="{% static "images/hi.jpg" %}" alt="Hi!" />
引用JS文件时使用:
代码语言:javascript复制{% load static %}
<script src="{% static "mytest.js" %}"></script>
某个文件多处被用到可以存为一个变量
代码语言:javascript复制{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>
使用get_static_prefix
代码语言:javascript复制{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />
或者
代码语言:javascript复制{% load static %}
{% get_static_prefix as STATIC_PREFIX %}
<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />
inclusion_tag
多用于返回html代码片段
示例:
templatetags/my_inclusion.py
代码语言:javascript复制from django import template
register = template.Library()
@register.inclusion_tag('result.html')
def show_results(n):
n = 1 if n < 1 else int(n)
data = ["第{}项".format(i) for i in range(1, n 1)]
return {"data": data}
templates/snippets/result.html
代码语言:javascript复制<ul>
{% for choice in data %}
<li>{{ choice }}</li>
{% endfor %}
</ul>
templates/index.html
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>inclusion_tag test</title>
</head>
<body>
{% load inclusion_tag_test %}
{% show_results 10 %}
</body>
</html>