Django(32)自定義過濾器

前言

雖然DTL給我們內置了許多好用的過濾器。但是有些時候還是不能滿足我們的需求。因此Django給我們提供了一個介面,可以讓我們自定義過濾器,實現自己的需求。
 

自定義過濾器

  1. 首先在某個app中,創建一個python包,叫做templatetags,注意,這個包的名字必須為templatetags,不然就找不到。

  2. 在這個templatetags包下面,創建一個python文件用來存儲過濾器。

  3. 在新建的python文件中,定義過濾器(也就是函數),這個函數的第一個參數永遠是被過濾的那個值,並且如果在使用過濾器的時候傳遞參數,那麼還可以定義另外一個參數。但是過濾器最多只能有2個參數。

  4. 在寫完過濾器(函數)後,要使用django.template.Library.filter進行註冊。

  5. 還要把這個過濾器所在的這個app添加到settings.INSTALLED_APS中,不然Django也找不到這個過濾器。

  6. 在模板中使用load標籤載入過濾器所在的python包。

  7. 可以使用過濾器了。

  8. 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 %}  <!--使用自定義過濾器-->
...
Tags: