Django(32)自定義過濾器
前言
雖然DTL
給我們內置了許多好用的過濾器。但是有些時候還是不能滿足我們的需求。因此Django
給我們提供了一個介面,可以讓我們自定義過濾器,實現自己的需求。
自定義過濾器
-
首先在某個
app
中,創建一個python
包,叫做templatetags
,注意,這個包的名字必須為templatetags
,不然就找不到。 -
在這個
templatetags
包下面,創建一個python
文件用來存儲過濾器。 -
在新建的
python
文件中,定義過濾器(也就是函數),這個函數的第一個參數永遠是被過濾的那個值,並且如果在使用過濾器的時候傳遞參數,那麼還可以定義另外一個參數。但是過濾器最多只能有2個參數。 -
在寫完過濾器(函數)後,要使用
django.template.Library.filter
進行註冊。 -
還要把這個過濾器所在的這個
app
添加到settings.INSTALLED_APS
中,不然Django也找不到這個過濾器。 -
在模板中使用
load
標籤載入過濾器所在的python包。 -
可以使用過濾器了。
-
django.template.Library.filter
還可以當作裝飾器來使用。如果filter
函數沒有傳遞任何參數,那麼將會使用這個函數的名字來作為過濾器的名字。當然如果你不想使用函數的名字來作為過濾器的名字,也可以傳遞一個name參數。示例程式碼如下:
@register.filter('my_greet')
def greet(value,word):
return value + word
時間過濾器案例
有時候經常會在朋友圈、微博中可以看到一條資訊發表的時間,並不是具體的時間,而是距離現在多久。比如剛剛,1分鐘前等。這個功能DTL是沒有內置這樣的過濾器的,因此我們可以自定義一個這樣的過濾器。示例程式碼如下:
# time_filter.py
@register.filter(name="time_since") # 將函數註冊到模版庫中當作過濾器
def time_since(value):
"""
time距離現在的時間間隔
1. 如果時間間隔小於1分鐘以內,那麼就顯示「剛剛」
2. 如果是大於1分鐘小於1小時,那麼就顯示「xx分鐘前」
3. 如果是大於1小時小於24小時,那麼就顯示「xx小時前」
4. 如果是大於24小時小於30天以內,那麼就顯示「xx天前」
5. 否則就是顯示具體的時間 2017/10/20 16:15
"""
if isinstance(value, datetime):
now = datetime.now()
timestamp = (now - value).total_seconds()
if timestamp < 60:
return "剛剛"
elif timestamp >= 60 and timestamp < 60 * 60:
minutes = int(timestamp /60)
return f"{minutes}分鐘前"
elif timestamp >= 60 * 60 and timestamp < 60 * 60 *24:
hours = int(timestamp / (60 * 60))
return f"{hours}小時前"
elif timestamp >= 60 * 60 * 24 and timestamp < 60 * 60 * 24 * 30:
days = int(timestamp / (60 * 60 * 24))
return f"{days}天前"
else:
return value.strftime("%Y/%m/%d %H:%M")
else:
return value
在模版中使用的示例程式碼如下:
{% load time_filter %} <!--載入自定義過濾器,time_filter是創建的python文件的名字-->
...
{% value|time_since %} <!--使用自定義過濾器-->
...