目录

一、模板简介

二、模板语法之变量

三、模板之过滤器

四、模板之标签

for标签

for ... empty

if 标签

with

五、自定义标签和过滤器

六、模板导入和继承

模板导入:

模板继承:

七、静态文件相关

除了使用static标签外还可以使用get_static_prefix

inclusion_tag


一、模板简介

首先我们来看一个例子:

def current_datetime(request):now = datetime.datetime.now()html = "<html><body>It is now %s.</body></html>" % nowreturn HttpResponse(html)

你可能已经注意到我们在例子视图中返回文本的方式有点特别。 也就是说,HTML被直接硬编码在 Python代码之中

尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不是一个好主意。 让我们来看一下为什么:

  • 对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。

  • Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。

  • 程序员编写 Python代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。

基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式,这就是本章要具体讨论的问题

python中Django框架中的模板: HTML代码 + 模板语法(DTL(Django Template Language))

def current_time(req):# ================================原始的视图函数# import datetime# now=datetime.datetime.now()# html="<html><body>现在时刻:<h1>%s.</h1></body></html>" %now# ================================django模板修改的视图函数# from django.template import Template,Context# now=datetime.datetime.now()# t=Template('<html><body>现在时刻是:<h1>{{current_date}}</h1></body></html>')# #t=get_template('current_datetime.html')# c=Context({'current_date':str(now)})# html=t.render(c)## return HttpResponse(html)#另一种写法(推荐)import datetimenow=datetime.datetime.now()return render(req, 'current_datetime.html', {'current_date':str(now)[:19]})
# 这样写就将处理过的now传到了current_datetime.html中,在html中就可以做相应的使用和处理了

模版语法重点:

  变量:{{ 变量名 }}   放到{{ }}里面相当于执行了print, 所以里边最终都是字符串

    1 深度查询 用点语法,可以连点,   深度查询时不可以加括号

    2 过滤器

  标签:{{%  % }}

二、模板语法之变量

在 Django 模板中遍历复杂数据结构的关键是点语法, 
语法:
变量渲染:{{变量名}}
变量深度查询: {{变量.索引/key/方法}}

我们拿一个实际的例子来介绍模板语法的变量使用:
views.py文件
在视图函数中后面使用render将locals()返回到html模板中, 在模板中就可以使用相应视图函数中所有的局部变量了

def template_test(request):name = 'lqz'li = ['lqz', 1, '18']dic = {'name': 'lqz', 'age': 18}ll2 = [{'name': 'lqz', 'age': 18},{'name': 'lqz2', 'age': 19},{'name': 'egon', 'age': 20},{'name': 'kevin', 'age': 23}]ll3=[]class Person:def __init__(self, name):self.name = namedef test(self):print('test函数')return 11@classmethoddef test_classmethod(cls):print('类方法')return '类方法'@staticmethoddef static_method():print('静态方法')return '静态方法'lqz = Person('lqz')egon = Person('egon')person_list = [lqz, egon]bo = Truete = test()import datetimenow=datetime.datetime.now()link1='<a href="https://www.baidu.com">点我<a>'from django.utils import safestringlink=safestring.mark_safe(link1)# html特殊符号对照表(http://tool.chinaz.com/Tools/htmlchar.aspx)# 这样传到前台不会变成特殊字符,因为django给处理过了dot='&spades;'# return render(request, 'template_index.html', {'name':name,'person_list':person_list})return render(request, 'template_index.html', locals())

模板中的 html文件
点语法也可以用来引用对象的方法(无参数方法)

            <p>{{ name }}</p><p>{{ li }}</p><p>{{ dic }}</p><p>{{ lqz }}</p><p>{{ person_list }}</p><p>{{ bo }}</p><p>{{ te }}</p><hr><h3>深度查询句点符</h3><p>{{ li.1 }}</p><p>{{ dic.name }}</p><p>{{ lqz.test }}</p><p>{{ lqz.name }}</p><p>{{ person_list.0 }}</p><p>{{ person_list.1.name }}</p><hr><h3>过滤器</h3>{#注意:冒号后面不能加空格#}<p>{{ now | date:"Y-m-d H:i:s" }}</p>{#如果变量为空,设置默认值,空数据,None,变量不存在,都适用#}<p>{{ name |default:'数据为空' }}</p>{#计算长度,只有一个参数#}<p>{{ person_list |length }}</p>{#计算文件大小#}<p>{{ 1024 |filesizeformat }}</p>{#字符串切片,前闭后开,前面取到,后面取不到#}<p>{{ 'hello world lqz' |slice:"2:-1" }}</p><p>{{ 'hello world lqz' |slice:"2:5" }}</p>{#截断字符,至少三个起步,因为会有三个省略号(传负数,1,2,3都是三个省略号)#}<p>{{ '刘清政 world lqz' |truncatechars:"4" }}</p>{#截断文字,以空格做区分,这个不算省略号#}<p>{{ '刘清政   是      大帅比 谢谢' |truncatewords:"1" }}</p><p>{{ link1 }}</p><p>{{ link1|safe }}</p><p>{{ link }}</p><p>&spades;</p><p>{{ dot }}</p>{#add   可以加负数,传数字字符串都可以#}<p>{{ "10"|add:"-2" }}</p><p>{{ li.1|add:"-2" }}</p><p>{{ li.1|add:2 }}</p><p>{{ li.1|add:"2" }}</p><p>{{ li.1|add:"-2e" }}</p>{#upper#}<p>{{ name|upper }}</p><p>{{ 'LQZ'|lower }}</p><hr><h3>模版语法之标签</h3>{#for 循环 循环列表,循环字典,循环列表对象#}<ui>{% for foo in dic %}{{ foo }}{% endfor %}{#也可以混用html标签#}{% for foo in li %}<ul>foo</ul>{% endfor %}</ui>{#表格#}<table border="1">{% for foo in ll2 %}<tr><td>{{ foo.name }}</td><td>{{ foo.age }}</td></tr>{% endfor %}</table><table border="1">{#'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 4,                             'revcounter0': 3, 'first': True, 'last': False}#}{% for foo in ll2 %}<tr><td>{{ forloop.counter }}</td><td>{{ foo.name }}</td><td>{{ foo.age }}</td></tr>{% endfor %}</table>{% for foo in ll5 %}<p>foo.name</p>{% empty %}<p>空的</p>{% endfor %}<hr><h3>if判断</h3>{% if name %}<a href="">hi {{ name }}</a><a href="">注销</a>{% else %}<a href="">请登录</a><a href="">注册</a>{% endif %}{#还有elif#}<hr><h3>with</h3>{% with ll2.0.name as n %}{{ n }}{% endwith %}{{ n }}{% load my_tag_filter %}{{ 3|multi_filter:3 }}{#传参必须用空格区分#}{% multi_tag 3 9 10 %}{#可以跟if连用#}{% if 3|multi_filter:3 > 9 %}<p>大于</p>{% else %}<p>小于</p>{% endif %}

三、模板之过滤器

过滤器语法:         {{obj|filter__name:param}} 变量名字|过滤器名称:变量
在Django中过滤器最多只能有两个参数, 第一个参数是在 | 前面传入的, 第二个参数是在过滤器后面:后面传入的

注意: 中间不能有空格

常见的过滤器:

default:
如果一个变量是false或者为空, 使用给定的默认值, 否则, 使用变量的值. 例如:

{{value|default:"nothing"}}

length:
返回值的长度. 它对字符串和列表起作用. 没有参数 例如:

{{value|length}}

例如:  如果 value 是 ['a', 'b', 'c', 'd'],那么输出是 4。

filesizeformat:
将值格式化为一个''人类可读的"文件尺寸 ,没有参数(例如 '13 KB''4.1 MB''102 bytes', 等等)

{{value|filesizeformat}}

例如:  如果 value 是 123456789,输出将会是 117.7 MB

date:
如果 value=datetime.datetime.now()

{{ value|date:"Y-m-d" }} 2019-01-10
{{ value|date:"Y年m月d日" }} 2019年01月10日

slice:
字符串切片
如果 value="hello world"

{{ value|slice:"2:-1" }}  # lloworld

truncatechars:
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
参数: 要截断的字符数
例如:

{{ value|truncatechars:9 }}  #超过9个字符的字符串将以...显示

truncatewords:
如果字符串单词多于指定的单词数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
参数: 要截断的单词数
例如:
value: my name is allen

{{ value|truncatechars:2 }}  #超过2个单词的字符串将以...显示  my name...

safe:
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:

value="<a href="">点击</a>"
{{value|safe}}

除了可以加过safe之后在视图层显示出来, 还可以在后台使用mark_safe()函数,在后台拼接出来的标签传进函数处理, 将得到的返回值传给模板层,再渲染到页面中,

其它过滤器(了解):
要注意不能有空格

过滤器 描述 示例
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转义,比如将”<”转换为”&lt”  
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:’*’ }} 返回 abc*45
length 返回列表中元素的个数或字符串长度  
length_is 检查列表,字符串长度是否符合指定的值 {{ ‘hello’| length_is:’3’ }}
linebreaks 用<p>或<br>标签包裹变量 {{ “Hi\n\nDavid”|linebreaks }} 返回<p>Hi</p><p>David</p>
linebreaksbr 用<br/>标签代替换行符  
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 }}
返回
yes
no
maybe

四、模板之标签

语法: {% %}

标签看起来像是这样的: {% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。一些标签需要开始和结束标签 (例如{% tag %} ...标签 内容 ... {% endtag %})。

常用标签的介绍:

for标签

遍历每一个元素:

{% for person in person_list %}<p>{{ person.name }}</p>
{% endfor %}

可以利用{% for obj in list reversed %}反向完成循环。

遍历一个字典:

{% for key,val in dic.items %}<p>{{ key }}:{{ val }}</p>
{% endfor %}

注:循环序号可以通过{{forloop}}显示  

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         本层循环的外层(父级)循环,循环嵌套时使用

for ... empty

for 标签带有一个可选的{% empty %} 从句,以便在给出的可迭代对象是空的或者没有被找到时,可以有所操作。当为空时执行empty后面的内容

{% for person in person_list %}<p>{{ person.name }}</p>{% empty %}<p>sorry,no person here</p>
{% endfor %}

if 标签

{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。

{% if num > 100 or num < 0 %}<p>无效</p>
{% elif num > 80 and num < 100 %}<p>优秀</p>
{% else %}<p>凑活吧</p>
{% endif %}

if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。

with

使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的, 
可以简单的记为给一个复杂的操作起别名

例如:
第一种写法:

{% with total=business.employees.count %}{{ total }} employee{{ total|pluralize }}
{% endwith %}
不要写成as

第二种写法: 给复杂操作起别名

{% with business.employees.count as a %}{{ a }} employee{{ total|pluralize }}
{% endwith %}

csrf_token

{% csrf_token%}

这个标签用于跨站请求伪造保护:

五、自定义标签和过滤器

1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.

2、在app中创建templatetags模块(模块名只能是templatetags)

3、在templatetags创建任意 .py 文件,如:my_tags.py

在py文件中写自定义的过滤器或者标签的时候要注意的:

  • 必须要定义register = template.Library()  并且register名字不可改变

  • 在定义之前使用register.filter|simple_tag装饰器来装饰才能实现相应的功能

  • 装饰器中可以传入参数,其中name不给定时: 在页面中使用load加载时默认使用定义时的函数名进行加载, 如果给定了name值,使用load加载时要使用给定的name值

from django import templatefrom django.utils.safestring import mark_saferegister = template.Library()   #register的名字是固定的,不可改变@register.filterdef filter_multi(v1,v2):return  v1 * v2<br>@register.simple_tagdef simple_tag_multi(v1,v2):return  v1 * v2<br>@register.simple_tagdef 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

{% load my_tags %} 

5、使用simple_tag和filter(如何调用)先使用load将定义好的过滤器或者标签加载出来

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

六、模板导入和继承

模板导入:

当有一个布局, 样式都很棒, 并且满足你的需求的前端模板, 然后又需要在不止一个页面中使用这个模板的时候, 就会用到模板导入, 导入模板的本质就是将模板的内容作为字符串复制过来,再使用mark_safe()函数处理, 然后在导入的地方显示到页面中

语法: {% include '模版名称' %}

 如:{% include 'adv.html' %}

模板继承:

Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。

模板继承详解:
首先有一个母版, 我们在做网站的时候,很多时候都会有一个母版, 在页面发生跳转的时候, 只是局部页面发生了变化, 局部变化我们在后面可以通过异步请求和使用ajax请求来进行局部刷新来实现, 这个时候就可以有一个页面来作为我们网站的模板, 然后再对应的位置留下block, block可以理解为一个个盒子, 留下盒子越多,模板的扩展性就越高, 在子模板中对该子模板需要显示和渲染的盒子进行数据渲染, 没有被渲染的盒子不会占位,也不会影响页面整体布局

关于模板继承中的Block:
模板继承中的block是模板继承中很重要的一环, 在母版的任意位置都可以设置block, 在母版的位置设置block的时候要注意给每个位置的block合适的名字, 然后在子模板中根据block的名字对相应需要渲染的block进行数据填充, 要注意页面代码要卸载bolck体内, 写在外面是渲染不到母版中相应的位置的.

通过从下面这个例子开始,可以容易的理解模版继承:
在这个例子中我们分别在title标签的内容、class=sidebar和id=content的div中中设置了block

<!DOCTYPE html>
<html lang="en">
<head><link rel="stylesheet" href="style.css"/><title>{% block title %}My amazing site{% 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进行数据填充
{% 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 %} 标签越好,越多base模板的扩展性越好。请记住,子模版不必定义全部父模版中的blocks,所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。

  • 如果你发现你自己在大量的模版中复制内容,那可能意味着你应该把内容移动到父模版中的一个 {% block %} 中。

  • 如果您需要从父模板获取块的内容,可以使用{{block.super}}。 如果要添加父块的内容而不是完全覆盖它,这将非常有用。在哪里使用{{block.super}},原来的内容就会放在哪里. 使用{{block.super}}插入的数据不会自动转义,因为必要时,它已在父模板中转义。

  • 为了更好的可读性,你也可以给你的 {% endblock %} 标签一个 名字 。例如:

    {% block content %}
    ...
    {% endblock content %}  

    在大型模版中,这个方法帮你清楚的看到哪一个  {% block %} 标签被关闭了。

  • 不能在一个模版中定义多个相同名字的 block 标签。

七、静态文件相关

之前我们在Django中使用静态文件的时候,是使用link标签将static文件中静态文件导进来的, 例如:

<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">

这样写是可以的, 但是我们考虑到settings中配置静态文件的变量STATIC_URL可能会被修改, 一旦被修改, 我们使用link标签写死的方式将不再生效, 我们能不能使用像反向解析的方式将路径动态的导入呢?

如果让我们自己写一个这样的标签应该怎样写呢?  思路就是自定义一个标签将settings中的STATIC_URL变量的值返回出来就可以了, 在我们的Django框架中是有这样的标签的, 就是static, 下面是使用该标签将static/images/hi.jpg静态文件导入的例子:

# 首先加载定义static标签的文件
{% load static %}<img src="{% static "images/hi.jpg" %}" alt="Hi!" />

引用JS文件时使用:

{% load static %}
<script src="{% static "mytest.js" %}"></script>

某个文件多处被用到可以存为一个变量

{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>

除了使用static标签外还可以使用get_static_prefix

使用get_static_prefix相当于获取了'/static/'放到路径中

{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />

或者使用get_static_prefix取别名后再使用

{% 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代码片段

详解inclusion_tag的工作原理:
首先我们来解释一下什么是html片段, 顾名思义, html片段不是一个完整的html, 他只是html中的一部分, 可以是一个div, 一个列表,一张图片等等, 
然后我们讲一下我们为什么要使用inclusion_tag以及它的应用场景
我们来举例说明: 比如我们在做网站的时候, 在侧边栏需要经常用到使用列表搭建的页面, 如果我们每个盒子都写在html中,代码量会很大,并且管理起来也比较麻烦, 这个时候如果能有一个方法能够动态的生成这些东西, 输入参数来控制列表的个数就好了, 这样的需求正是Inclusion_tag所能实现的,它能够动态的生成一个html片段, 然后根据用户的需求填充到页面相应的位置

inclusion_tag的工作原理:

  • 首先根据自定义标签和过滤器一样, 需要先在项目根目录创建templatetags文件夹, 然后再文件夹里边创建一个py文件,在py文件中按照标准导入模块, 设置变量

  • 在定义函数的时候,和定义标签和过滤器使用不同的装饰器, 装饰器一定要传入参数, 传入的第一个参数是要返回的html片段,是一个html文件, 在该html文件中写一个html片段,后面可以传入name参数来给下面的函数起别名

  • 然后紧接着装饰器写inclusion_tag有关的函数, 函数名字可以自己定义, 函数可以接受多个参数, 函数的参数是在目标html文件中使用标签导入html片段的时候传入的, 然后再函数体中可以写一些处理逻辑,(比如从数据库中获取数据返回给html片段中使用等等), 定义的函数必须要有一个返回值, 返回值需是一个字典类型, 字典中可以返回多个值, 可以返回一个变量,一个对象,一个列表等等, 该函数的返回值是返回到函数装饰器传入的html片段的html文件中的, 在html文件中可以使用模板语言对函数的返回值做相应的处理, 到这个阶段html片段基本就渲染完毕了,

  • 最后就是在其他完整的html文件中插入该html片段文件, 和导入标签的语法一样,先使用load将定义函数的py文件导入进去,然后在目标文件需要的位置导入html片段, 这就是inclusion完整的工作原理和工作流程

使用inclusion_tag的步骤

1 前面几步跟自定义标签和过滤器一样,只不过使用的装饰器不同,
    2 装饰器:@register.inclusion_tag('inclusiontag.html',name='lqz'),第一个参数是要操作的模板
    3 返回一个字典,字典中的值,可以在inclusiontag中使用
    4 使用:
        {%load 你写的那个py文件%}
        {% 函数名字 参数 参数 %}

注意:

  • 使用inclusion_tag方法的时候, 只能自定义,没有内置, 因为系统不知道要返回哪一个html片段

  • 装饰器同样可以给函数起别名, 在使用的时候直接使用别名即可

  • 返回的值必须要是一个字典

示例:

templatetags/my_inclusion.py

from django import templateregister = 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  (这个就是html片段)

<ul>{% for choice in data %}<li>{{ choice }}</li>{% endfor %}
</ul>

templates/index.html   (这个是目标html ,就是将html传入到该文件中的)

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

Django框架的模板层详解相关推荐

  1. django框架中的QuerySet详解及相关操作

    QuerySet概念 从数据库中查询出来的结果一般是一个集合,这个集合叫做 QuerySet. <QuerySet [<Goods: Goods object (8)>, <G ...

  2. Android Binder框架实现之Parcel详解之基本数据的读写

       Android Binder框架实现之Parcel详解之基本数据的读写 Android Binder框架实现目录: Android Binder框架实现之Binder的设计思想 Android ...

  3. Android Binder框架实现之bindService详解

        Android Binder框架实现之bindService详解 Android Binder框架实现目录: Android Binder框架实现之Binder的设计思想 Android Bi ...

  4. caffe网络模型各层详解(中文版)

    caffe网络模型各层详解(中文版) 参考网址:https://blog.csdn.net/qq_34220460/article/details/79872830 一.数据层及参数 要运行caffe ...

  5. java集合框架史上最详解(list set 以及map)

    title: Java集合框架史上最详解(list set 以及map) tags: 集合框架 list set map 文章目录 一.集合框架总体架构 1.1 集合框架在被设计时需满足的目标 1.2 ...

  6. 第三百一十节,Django框架,模板语言

    第三百一十节,Django框架,模板语言 模板语言就是可以将动态数据在html模板渲染的语言 一.接收值渲染 locals()函数,写在请求响应render()函数里,可以将逻辑处理函数里的变量传到h ...

  7. 超轻量级DI容器框架Google Guice与Spring框架的区别教程详解及其demo代码片段分享...

    超轻量级DI容器框架Google Guice与Spring框架的区别教程详解及其demo代码片段分享 DI框架 Google-Guice入门介绍 转载于:https://www.cnblogs.com ...

  8. python string模块template_Python - 定制pattern的string模板(template) 详解

    定制pattern的string模板(template) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/28625179 s ...

  9. pythondjango教程_Python 中Django安装和使用教程详解

    一.安装 一般使用cmd 安装就可以 手动安装通过下载方式 二.配置使用 1.通过cmd新建一个项目,我是在桌面新建 上面命令会在桌面新建pythonDjango文件夹,在里面会生成如下图两个文件 m ...

最新文章

  1. AI一分钟|百度与中国联通成立“5G+AI联合实验室”;SpaceX将向国际空间站发送AI机器人...
  2. 从Google代码库找到的好东西
  3. 技术文章精美配图模板网站推荐-创客贴
  4. nlp mrc的损失是什么_你对NLP的迁移学习爱的有多深?21个问题弄懂最新的NLP进展...
  5. 软件系统换服务器地址,天正软件客户端修改服务器地址
  6. 腾讯python面试题_面试题 | 腾讯数据分析面试题分享
  7. 负数如何归一化处理_「译」 对比归一化和标准化——量化分析
  8. VB谨慎使用IsMissing函数
  9. aliyun gradle 代理_gradle:现代高效的java构建工具
  10. 网络协议 21 - RPC 协议(中)- 基于 JSON 的 RESTful 接口协议
  11. 华为私密相册计算机找回密码,华为手机进入隐私空间的密码忘记了怎么办
  12. 办公室电脑如何共享计算机,办公室电脑如何互相共享文件?
  13. 【BZOJ4049】【Cerc2014】 Mountainous landscape 【凸包】【线段树】
  14. dfuse 的 GraphQL 端点现在提供经过 ABI 解码的数据库行为信息
  15. matlab 光平面标定代码,线结构光视觉传感器/线激光深度传感器标定工具(matlab)...
  16. telnet 访问80端口
  17. 深度学习DeepLearning
  18. 书籍勘误表整理(2019.5.7)
  19. 少年,单元测试的两个流派了解下!
  20. 关于ipad mini2升级到12.5.4(问题解答)

热门文章

  1. Unity学习之PD 过河游戏智能帮助实现
  2. Angular 4.0_在线竞拍网站(4)
  3. 旅通软件:旅行社如何快人一步?
  4. Advanced Duplicate Cleane‪r‬ for Mac(高级重复文件清理软件)
  5. 从语音切入直播,但红豆live的野心不只是语音
  6. 如何对图片进行旋转?这些工具能将图片进行旋转
  7. 德国马牌轮胎母公司大陆集团首发绿色概念轮胎
  8. StdOS之运行指示灯
  9. 你对ISO了解多少!
  10. 5道面试逻辑智力测试题内附详细答案