目录
一、模板简介
二、模板语法之变量
三、模板之过滤器
四、模板之标签
for标签
for ... empty
if 标签
with
五、自定义标签和过滤器
六、模板导入和继承
模板导入:
模板继承:
七、静态文件相关
除了使用static标签外还可以使用get_static_prefix
inclusion_tag
首先我们来看一个例子:
def current_datetime(request):
now = datetime.datetime.now()
html = "It is now %s." % now
return 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="现在时刻:%s.
" %now
# ================================django模板修改的视图函数
# from django.template import Template,Context
# now=datetime.datetime.now()
# t=Template('现在时刻是:{{current_date}}
')
# #t=get_template('current_datetime.html')
# c=Context({'current_date':str(now)})
# html=t.render(c)
#
# return HttpResponse(html)
#另一种写法(推荐)
import datetime
now=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 = name
def test(self):
print('test函数')
return 11
@classmethod
def test_classmethod(cls):
print('类方法')
return '类方法'
@staticmethod
def static_method():
print('静态方法')
return '静态方法'
lqz = Person('lqz')
egon = Person('egon')
person_list = [lqz, egon]
bo = True
te = test()
import datetime
now=datetime.datetime.now()
link1='点我'
from django.utils import safestring
link=safestring.mark_safe(link1)
# html特殊符号对照表(http://tool.chinaz.com/Tools/htmlchar.aspx)
# 这样传到前台不会变成特殊字符,因为django给处理过了
dot='♠'
# return render(request, 'template_index.html', {'name':name,'person_list':person_list})
return render(request, 'template_index.html', locals())
模板中的 html文件
点语法也可以用来引用对象的方法(无参数方法)
{{ name }}
{{ li }}
{{ dic }}
{{ lqz }}
{{ person_list }}
{{ bo }}
{{ te }}
深度查询句点符
{{ li.1 }}
{{ dic.name }}
{{ lqz.test }}
{{ lqz.name }}
{{ person_list.0 }}
{{ person_list.1.name }}
过滤器
{#注意:冒号后面不能加空格#}
{{ now | date:"Y-m-d H:i:s" }}
{#如果变量为空,设置默认值,空数据,None,变量不存在,都适用#}
{{ name |default:'数据为空' }}
{#计算长度,只有一个参数#}
{{ person_list |length }}
{#计算文件大小#}
{{ 1024 |filesizeformat }}
{#字符串切片,前闭后开,前面取到,后面取不到#}
{{ 'hello world lqz' |slice:"2:-1" }}
{{ 'hello world lqz' |slice:"2:5" }}
{#截断字符,至少三个起步,因为会有三个省略号(传负数,1,2,3都是三个省略号)#}
{{ '刘清政 world lqz' |truncatechars:"4" }}
{#截断文字,以空格做区分,这个不算省略号#}
{{ '刘清政 是 大帅比 谢谢' |truncatewords:"1" }}
{{ link1 }}
{{ link1|safe }}
{{ link }}
♠
{{ dot }}
{#add 可以加负数,传数字字符串都可以#}
{{ "10"|add:"-2" }}
{{ li.1|add:"-2" }}
{{ li.1|add:2 }}
{{ li.1|add:"2" }}
{{ li.1|add:"-2e" }}
{#upper#}
{{ name|upper }}
{{ 'LQZ'|lower }}
模版语法之标签
{#for 循环 循环列表,循环字典,循环列表对象#}
{% for foo in dic %}
{{ foo }}
{% endfor %}
{#也可以混用html标签#}
{% for foo in li %}
foo
{% endfor %}
{#表格#}
{% for foo in ll2 %}
{{ foo.name }}
{{ foo.age }}
{% endfor %}
{#'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 4, 'revcounter0': 3, 'first': True, 'last': False}#}
{% for foo in ll2 %}
{{ forloop.counter }}
{{ foo.name }}
{{ foo.age }}
{% endfor %}
{% for foo in ll5 %}
foo.name
{% empty %}
空的
{% endfor %}
if判断
{% if name %}
hi {{ name }}
注销
{% else %}
请登录
注册
{% endif %}
{#还有elif#}
with
{% 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 %}
大于
{% else %}
小于
{% 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="点击"
{{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 | 判断是否可以被数字整除 | |
escape | 按HTML转义,比如将”<”转换为”<” | |
filesizeformat | 增加数字的可读性,转换结果为13KB,89MB,3Bytes等 | |
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 | 用 或 |
{{ “Hi\n\nDavid”|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] |
slugify | 在字符串中留下减号和下划线,其它符号删除,空格用减号替换 | |
stringformat | 字符串格式化,语法同python | |
time | 返回日期的时间部分 | |
timesince | 以“到现在为止过了多长时间”显示时间变量 | 结果可能为 45days, 3 hours |
timeuntil | 以“从现在开始到时间变量”还有多长时间显示时间变量 | |
title | 每个单词首字母大写 | |
truncatewords | 将字符串转换为省略表达方式 | |
truncatewords_html | 同上,但保留其中的HTML标签 | |
urlencode | 将字符串中的特殊字符转换为url兼容表达方式 | {{ ‘http://www.aaa.com/foo?a=b&b=c’ | urlencode}} |
urlize | 将变量字符串中的url由纯文本变为链接 | |
wordcount | 返回变量字符串中的单词数 | |
yesno | 将布尔变量转换为字符串yes, no 或maybe | |
语法: {% %}
标签看起来像是这样的: {% tag %}
。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。一些标签需要开始和结束标签 (例如{% tag %} ...
标签 内容 ... {% endtag %})。
常用标签的介绍:
遍历每一个元素:
{% for person in person_list %}
{{ person.name }}
{% endfor %}
可以利用{% for obj in list reversed %}反向完成循环。
遍历一个字典:
{% for key,val in dic.items %}
{{ key }}:{{ val }}
{% 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 %} 从句,以便在给出的可迭代对象是空的或者没有被找到时,可以有所操作。当为空时执行empty后面的内容
{% for person in person_list %}
{{ person.name }}
{% empty %}
sorry,no person here
{% endfor %}
{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
{% if num > 100 or num < 0 %}
无效
{% elif num > 80 and num < 100 %}
优秀
{% else %}
凑活吧
{% endif %}
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的,
可以简单的记为给一个复杂的操作起别名
例如:
第一种写法:
{% 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 template
from django.utils.safestring import mark_safe
register = template.Library() #register的名字是固定的,不可改变
@register.filter
def filter_multi(v1,v2):
return v1 * v2
@register.simple_tag
def simple_tag_multi(v1,v2):
return v1 * v2
@register.simple_tag
def my_input(id,arg):
result = "" %(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
{% block title %}My amazing site{% endblock %}
{% block content %}{% endblock %}
这个模版,我们把它叫作 base.html(母版)
, 它定义了一个可以用于两列排版页面的简单HTML骨架。“子模版”的工作是用它们的内容填充空的blocks。
在这个例子中, block
标签定义了三个可以被子模版内容填充的block。 block
告诉模版引擎: 子模版可能会覆盖掉模版中的这些位置。
子模版可能看起来是这样的:
首先将模板继承过来
{% extends "base.html" %}
然后按照名字对各个block进行数据填充
{% block title %}My amazing blog{% endblock %}
{% block content %}
{% for entry in blog_entries %}
{{ entry.title }}
{{ entry.body }}
{% endfor %}
{% endblock %}
extends
标签是这里的关键。它告诉模版引擎,这个模版“继承”了另一个模版。当模版系统处理这个模版时,首先,它将定位父模版——在此例中,就是“base.html”。
那时,模版引擎将注意到 base.html
中的三个 block
标签,并用子模版中的内容来替换这些block。根据 blog_entries
的值,输出也就是填充好的子模板可能看起来是这样的:
My amazing blog
Entry one
This is my first entry.
Entry two
This is my second entry.
请注意,子模版并没有定义 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文件中静态文件导进来的, 例如:
这样写是可以的, 但是我们考虑到settings中配置静态文件的变量STATIC_URL可能会被修改, 一旦被修改, 我们使用link标签写死的方式将不再生效, 我们能不能使用像反向解析的方式将路径动态的导入呢?
如果让我们自己写一个这样的标签应该怎样写呢? 思路就是自定义一个标签将settings中的STATIC_URL变量的值返回出来就可以了, 在我们的Django框架中是有这样的标签的, 就是static, 下面是使用该标签将static/images/hi.jpg静态文件导入的例子:
# 首先加载定义static标签的文件
{% load static %}
引用JS文件时使用:
{% load static %}
某个文件多处被用到可以存为一个变量
{% load static %}
{% static "images/hi.jpg" as myphoto %}
使用get_static_prefix相当于获取了'/static/'放到路径中
{% load static %}
或者使用get_static_prefix取别名后再使用
{% load static %}
{% get_static_prefix as STATIC_PREFIX %}
多用于返回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 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 (这个就是html片段)
{% for choice in data %}
- {{ choice }}
{% endfor %}
templates/index.html (这个是目标html ,就是将html传入到该文件中的)
inclusion_tag test
{% load inclusion_tag_test %}
{% show_results 10 %}