Django自定義過濾器
為什麼要自定義過濾器?
Django中雖然已經內建了很多過濾器,但是並不能滿足我們的日常開發,所以我們需要自定義過濾器。
首先我們先搭建好一個測試環境。
在一個新建的專案中建立一個article
的app,然後在article
中新建一個urls.py
的檔案,然後在templates
中新建一個index.html
的檔案,(如果沒有templates這個資料夾需要手動建立),然後進行配置,使article
中的views對index.html
進行渲染。直至配置好測試環境。
在一切配置好了之後,然後在article
中新建一個名為templatetags
的package
。
注意: 必須是一個包,並且包的名字也必須為templatetags
package和資料夾的區別:
package
中會有一個__init__.py
的檔案。只用擁有__init__.py
的package
才能被匯入。建包方法:
article
資料夾上右鍵=>new=>Python Package.然後名字為templatetags
然後在templatetags
中新建一個python檔案,檔名就可以隨便取了,我這裡就新建了一個my_filter.py
的檔案。
在裡面寫入我們自定義的過濾器的規則:
from django import template
register = template.Library()
#過濾器函式主體,第一個引數是過濾器前面的值, 第二個引數是過濾器後面的值
#可以不用有第二個引數,但是必須要有第一個引數,引數最多兩個
def greet(value,word):
return value + word
#註冊自定義的過濾器
# 過濾器的名字 過濾器的主體函式
register.filter('greet',greet)
這裡我麼就自定義好了一個過濾器,它的功能是將字元竄進行拼接。
然後在views中寫入程式碼
from django.shortcuts import render
# Create your views here.
def index(request):
context = { 'value':'張三'}
return render(request,'index.html',context=context)
然後配置url,然後在index.html
編寫程式碼:
首先,要想我們自定義的過濾器被執行,我們必須先將包含過濾器的app
進行註冊。即將這裡的article
新增到settings.INSTALLED_APS
中,不然Django也找不到這個過濾器。
其次,在渲染的html
檔案中的程式碼最上面載入自定義的過濾器:
{% load my_filter %}
這裡的my_filter
是我定義過濾器的檔名。
這樣,在html
中才能使用我們自定義的過濾器。
然後在index.html
中的body中寫入程式碼:
{{ value|greet:'world' }}
接下來就自行輸入網址,和改變引數進行測試。
這樣,我們的過濾器就從定義到使用的完全弄好了。
總結(建立過濾器的基本步驟):
- 首先在某個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
引數。
實戰案例 :自定義時間計算過濾器
有時候經常在朋友圈,微博中可以看到一條資訊發表的時間,並不是具體的時間,而是距離現在多久,比如:剛剛
,1分鐘前
等,DTL內建的過濾器是沒有這個功能的。因此我們需要自定義一個這樣的過濾器。
首先我們先開啟my_filter.py
這個檔案。
修改程式碼為:
from django import template
register = template.Library()
#過濾器函式主體,第一個引數是過濾器前面的值, 第二個引數是過濾器後面的值
#可以不用有第二個引數,但是必須要有第一個引數,引數最多兩個
@register.filter('greet') #和下面的register.filter('greet',greet)功能是一樣的
#1.可以不用傳引數,即預設使用下面的函式名作為過濾器的名字
#2.也可以傳入一個引數,即自定義過濾器的名字。
#3.最多隻能傳一個引數。
def greet(value,word):
return value + word
#註冊自定義的過濾器
# 過濾器的名字 過濾器的主體函式
register.filter('greet',greet)
然後我們使用了另外一種方法來註冊我們的過濾器。這樣我們就可以把下面的register.filter('greet',greet)
刪掉了也能實現效果。
接下來我們在my_filter.py
中自定義我們的時間過濾器
from django import template
from datetime import datetime
register = template.Library()
@register.filter
def time_since(value):
'''
time距離現在時間的間隔
1.如果時間間隔小於一分鐘以前,那麼就顯示剛剛。
2.如果是大於一分鐘小於一小時,那麼就顯示xx分鐘前
3.如果是大於一小時小於24小時,那麼就是顯示xx小時以前
4.如果是大於24 小時小於30天以內,那麼就顯示xx天以前
5.否則就顯示具體的時間 2017-10-04 12:45
'''
if not isinstance(value,datetime):
return value
now = datetime.now()
#time.total_seconds()將時間轉化為秒數
timestamp = (now - value).total_seconds()
if timestamp < 60:
return '剛剛'
elif timestamp > 60 and timestamp < 60*60:
minutes = int(timestamp/60)
return '%s分鐘前' % minutes
elif timestamp > 60*60 and timestamp < 60*60*24:
hours = int(timestamp/60/60)
return '%s小時前' % hours
elif timestamp > 60*60*24 and timestamp < 60*60*24*30:
days = int(timestamp/60/60/24)
return '%s天前' % days
else:
return value.strftime("%Y-%m-%d %e:%M")
在views中傳遞一個引數:
from django.shortcuts import render
from datetime import datetime
# Create your views here.
def index(request):
context = {'value':'張三','time':datetime(year=2018,month=8,day=20,hour=19,minute=8,second=0)}
return render(request,'index.html',context=context)
然後在index.html
中使用time_since
過濾器
首先在檔案最上面新增一行程式碼載入我們的過濾器。
{% load my_filter %}
然後在body中寫入
{{ time|time_since }}
然後就可以檢視效果了,如果需要改變時間,只需要去views中修改time
的值就行了。
==注意:==如果測試不成功,請仔細按照上面的總結來檢查哪一步出錯了。