现在我们已经很熟悉Django的MTV模式了。模板(模板)负责如何去展示数据,而视图(视图)负责筛选出正确的数据,因此通常来说逻辑都是放到视图中的,但模板也需要一些和表示相关的逻辑:比如循环展示(如<代码> {%……%}代码>),或者以某种特定格式输出(如<代码> {{…|日期:‘Y-m-d}}> 代码)等,这些功能都是靠模板的过滤器(过滤器)和标签(标签)实现的。
Django的模板语言包含了很多内置的过滤器和标签,设计目的是满足应用需要占位逻辑需求。但有的时候这些通用的功能满足不了你的某些需求,这时候就需要自定义过滤器和标签来实现了。
要在Django中使用模板过滤器或标签,就首先得注册它们。
注册方法如下:
-
<李>在应用中新建名为templatetags的目录(方便起见,教程选择了这条个应用)李>
<李>在此目录中新建名为__init__。py的空文件,使得此目录被视作一个Python的包李>
<李>在此目录中新建python文件(比如my_filters_and_tags。py),就可以在里面愉快的写代码啦李>
完成后的目录结构如下:
/条 __init__ . py views.py models.py #新增目录 templatetags/__init__。py #空文件 my_filters_and_tags。py #即将写代码的地方 …
-
<李>目录必须位于已注册的应用程序中,这是出于安全性的考虑李>
<李>新建目录后,必须手动重启服务器,里面的过滤器和标签才能生效
李>
前置条件就完成了,接下来我们看看如何写一个模板过滤器。
过滤器过滤的表现形式为紧跟在上下文后面的管道符|,管道符后面是过滤器的名称:{{…| filter_name}}。有的过滤器还可以带有参数:<代码> {{…| filter_name: var}} 代码>。
注意过滤器名称的冒号后面不能有空格。
过滤器这个名字可能会让你误认为它只是用来筛选某些特定数据的,但实际上它远不止这点功能。它可以改变上下文的最终展示效果,也可以将上下文通过运算输出为特定的值。
要成为一个可用的过滤器,文件中必须包含一个名为<代码> 代码>注册的模块级变量,它是一个<代码>模板。图书馆> 代码实例,所有的过滤器均在其中注册,所以在<代码> my_filter_and_tags。py 代码>文件中输入以下内容:
文章/templatetags/my_filter_and_tags.py 从django导入模板 注册=template.Library ()
接下来就可以像写普通的Python函数一样写过滤器了:
文章/templatetags/my_filter_and_tags.py 从django导入模板 注册=template.Library () @register.filter (name=白谩? def转移(值,参数): ”“”将输出强制转换为字符串参数“”“ 返回参数 @register.filter () def低(价值): ”“”将字符串转换为小写字符”“ 返回value.lower ()
过滤器可以通过装饰器进行注册。若注册装饰器中携带了名参数,则其值为此滤波器的名称,若未携带,则函数名就是过滤器的名称。
过滤器必须是有一到两个参数的Python函数。第一个参数是上下文本身,第二个参数则由滤波器提供。举个栗子,在过滤器<代码> {{var | foo:“酒吧”}}代码>中,变量var为第一个参数,变量杆则作为第二个参数。
调用这些过滤器的方法是在模板文件中用<代码>{%加载…%}> 代码将过滤器文件的名称加载进去,像这样:
#任意模板文件中 {%负载my_filters_and_tags %} {{' ABC ' |转移:“酷”}}#输出:“酷” {{低' ABC ' |}} #输出:“ABC”
了解完过滤器的使用方法后,下面来写点更实用的功能。
对人类这种生物来说,相对时间通常比绝对时间要更容易阅读。发表于3天前可以轻易得知此文章刚发表不久;而发表于2019年8月10日你还得想想今天到底几号来着。
因此写一个显示相对日期的time_since_zh过滤器:
文章/templatetags/my_filter_and_tags.py … django。跑龙套进口时区 导入数学 #获取相对时间 @register.filter (name=' timesince_zh ') def time_since_zh(价值): 现在=timezone.now () diff=现在-价值 如果diff.days==0和diff.seconds祝辞=0和diff.seconds & lt;60: 返回“刚刚” 如果diff.days==0和diff.seconds祝辞=60,diff.seconds & lt;3600: 返回str (math.floor (diff。秒/60))+“分钟前” 如果diff.days==0和diff.seconds祝辞=3600和diff.seconds & lt;86400: 返回str (math.floor (diff。秒/3600))+“小时前” 如果diff.days祝辞=1和diff.days & lt;30: 返回str (diff.days) + "天前” 如果diff.days祝辞=30 diff.days & lt;365: 返回str (math.floor (diff。天/30))+个月前” 如果diff.days祝辞=365: 返回str (math.floor (diff。天/365))+“年前”Django自定义模板过滤器和标签的实现方法