ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 第五节:自定义过滤器 # 自定义模版过滤器 虽然`DTL`给我们内置了许多好用的过滤器。但是有些时候还是不能满足我们的需求。因此`Django`给我们提供了一个接口,可以让我们自定义过滤器,实现自己的需求。 模版过滤器必须要放在`app`中,并且这个`app`必须要在`INSTALLED_APPS`中进行安装。然后再在这个`app`下面创建一个`Python包`叫做`templatetags`。再在这个包下面创建一个`python文件`。比如`app`的名字叫做`book`,那么项目结构如下: ``` <pre class="calibre12">``` - book - views.py - urls.py - models.py - templatetags - my_filter.py ``` ``` 在创建了存储过滤器的文件后,接下来就是在这个文件中写过滤器了。过滤器实际上就是python中的一个函数,只不过是把这个函数注册到模板库中,以后在模板中就可以使用这个函数了。但是这个函数的参数有限制,第一个参数必须是这个过滤器需要处理的值,第二个参数可有可无,如果有,那么就意味着在模板中可以传递参数。**并且过滤器的函数最多只能有两个参数**。在写完过滤器后,再使用`django.template.Library`对象注册进去。示例代码如下: ``` <pre class="calibre12">``` <span class="hljs-keyword">from</span> django <span class="hljs-keyword">import</span> template <span class="hljs-title"># 创建模板库对象</span> register = template.Library() <span class="hljs-title"># 过滤器函数</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">mycut</span><span class="hljs-params">(value,mystr)</span>:</span> <span class="hljs-keyword">return</span> value.replace(mystr) <span class="hljs-title"># 将函数注册到模板库中</span> register.filter(<span class="hljs-string">"mycut"</span>,mycut) ``` ``` 以后想要在模板中使用这个过滤器,就要在模板中`load`一下这个过滤器所在的模块的名字(也就是这个python文件的名字)。示例代码如下: ``` <pre class="calibre12">``` {% load my_filter %} ``` ``` ### 自定义时间计算过滤器: 有时候经常会在朋友圈、微博中可以看到一条信息发表的时间,并不是具体的时间,而是距离现在多久。比如`刚刚`,`1分钟前`等。这个功能`DTL`是没有内置这样的过滤器的,因此我们可以自定义一个这样的过滤器。示例代码如下: ``` <pre class="calibre12">``` <span class="hljs-title"># time_filter.py文件</span> <span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime <span class="hljs-keyword">from</span> django <span class="hljs-keyword">import</span> template register = template.Library() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">time_since</span><span class="hljs-params">(value)</span>:</span> <span class="hljs-string">""" time距离现在的时间间隔 1. 如果时间间隔小于1分钟以内,那么就显示“刚刚” 2. 如果是大于1分钟小于1小时,那么就显示“xx分钟前” 3. 如果是大于1小时小于24小时,那么就显示“xx小时前” 4. 如果是大于24小时小于30天以内,那么就显示“xx天前” 5. 否则就是显示具体的时间 2017/10/20 16:15 """</span> <span class="hljs-keyword">if</span> isinstance(value,datetime): now = datetime.now() timestamp = (now - value).total_seconds() <span class="hljs-keyword">if</span> timestamp < <span class="hljs-params">60</span>: <span class="hljs-keyword">return</span> <span class="hljs-string">"刚刚"</span> <span class="hljs-keyword">elif</span> timestamp >= <span class="hljs-params">60</span> <span class="hljs-keyword">and</span> timestamp < <span class="hljs-params">60</span>*<span class="hljs-params">60</span>: minutes = int(timestamp / <span class="hljs-params">60</span>) <span class="hljs-keyword">return</span> <span class="hljs-string">"%s分钟前"</span> % minutes <span class="hljs-keyword">elif</span> timestamp >= <span class="hljs-params">60</span>*<span class="hljs-params">60</span> <span class="hljs-keyword">and</span> timestamp < <span class="hljs-params">60</span>*<span class="hljs-params">60</span>*<span class="hljs-params">24</span>: hours = int(timestamp / (<span class="hljs-params">60</span>*<span class="hljs-params">60</span>)) <span class="hljs-keyword">return</span> <span class="hljs-string">"%s小时前"</span> % hours <span class="hljs-keyword">elif</span> timestamp >= <span class="hljs-params">60</span>*<span class="hljs-params">60</span>*<span class="hljs-params">24</span> <span class="hljs-keyword">and</span> timestamp < <span class="hljs-params">60</span>*<span class="hljs-params">60</span>*<span class="hljs-params">24</span>*<span class="hljs-params">30</span>: days = int(timestamp / (<span class="hljs-params">60</span>*<span class="hljs-params">60</span>*<span class="hljs-params">24</span>)) <span class="hljs-keyword">return</span> <span class="hljs-string">"%s天前"</span> % days <span class="hljs-keyword">else</span>: <span class="hljs-keyword">return</span> value.strftime(<span class="hljs-string">"%Y/%m/%d %H:%M"</span>) <span class="hljs-keyword">else</span>: <span class="hljs-keyword">return</span> value register.filter(<span class="hljs-string">"time_since"</span>,time_since) ``` ``` 在模版中使用的示例代码如下: ``` <pre class="calibre12">``` {% load time_filter %} ... {% value|time_since %} ... ``` ``` 为了更加方便的将函数注册到模版库中当作过滤器。也可以使用装饰器来将一个函数包装成过滤器。示例代码如下: ``` <pre class="calibre12">``` <span class="hljs-keyword">from</span> django <span class="hljs-keyword">import</span> template register = template.Library() <span class="hljs-class">@register.filter(name='mycut')</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">mycut</span><span class="hljs-params">(value,mystr)</span>:</span> <span class="hljs-keyword">return</span> value.replace(mystr,<span class="hljs-string">""</span>) ``` ```