django中自定義標籤和過濾器
準備(必需)工作:
1 在某個app下建立一個名為templatetags(必需,且包名不可變)的包。假設我們在名為polls的app下建立了一個templatetags的包,並在該包下建立了一個名為mytags的檔案。那麼目錄結構看起來應該就像這樣:
polls/
__init__.py
models.py
templatetags/
__init__.py
mytags.py
views.py
2 settings檔案中的INSTALLD_APPS內必須含有該app。接下來,我們需要確認settings檔案中的INSTALLED_APPS變數中已經有了polls
NSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls',
)
3 接下來在mytags檔案中寫入如下幾行
from django import template
register = template.Library()
4 在模板中使用{% load %} 標籤裝載自定義標籤或者裝飾器
{% load mytags %}
自定義過濾器:
1 自定義過濾器實際上就是寫一個函式
2 django會將過濾器前的值傳入該函式
3 函式完成後,需要進行登記register
因為第二步django已經幫我們完成,所以我們實際上只需要自己完成第一步和第三步
例項:寫一個自動省略多餘字串的過濾器
1 定義一個 truncate_chars 函式
# 若字串長度大於30,則省略之後的內容,否則原樣輸出該字串。引數value就是過濾器前的值 def truncate_chars(value): if value.__len__() > 30: return '%s......'% value[0:30] else: return value
2 register該函式
# 登記
register.filter('truncate_chars',truncate_chars)
def truncate_chars(value):
if value.__len__() > 30:
return '%s......'% value[0:30]
else:
return value
Library.filter(name,function,is_safe=False,needs_autoescape=False,excepts_localtime=False)函式預設需要兩個引數,name是裝飾器的名稱(字串型別),function是函式名。後面三個引數可以參考 官方文件 我們也可以通過裝飾器進行登記
@register.filter(name='truncate_filter')
def truncate_chars(value):
if value.__len__() > 30:
return '%s......'% value[0:30]
else:
return value
如果沒有使用name引數,django預設會將函式名作為name引數的值,所以下面的程式碼和上面的程式碼作用相同。
@register.filter
def truncate_chars(value):
if value.__len__() > 30:
return '%s......'% value[0:30]
else:
return value
自定義標籤
自定義標籤相對於自定義過濾器來說要複雜很多,因為自定義標籤可以做任何事情!
自定義標籤分為很多型別
1 簡單標籤 Simple tags
2 內含標籤 Inclusion tags
3 分配標籤 Assignment tags
一 簡單標籤
import datetime
from django import template
register = template.Library()
@register.simple_tag
def current_time(format_string):
return datetime.datetime.now().strftime(format_string)
Library.simple_tag(takes_context=True) takes_context=True引數可以讓我們訪問模板的當前環境上下文,即將當前環境上下文中的引數和值作為字典傳入函式中的一個名為context的引數
@register.simple_tag(takes_context=True)
def current_time(context, format_string):
timezone = context['timezone']
return your_get_current_time_method(timezone, format_string)
當使用take_context=True時,函式的第一個引數必需為context。也可以使用name引數對函式進行重新命名。
二 內含標籤
這種型別的標籤可以被其他模板進行渲染,然後將渲染結果輸出
Library.inclusion_tag()支援take_context=True,用法類似Library.simple_tag()
from django import template
register = template.Library()
@register.inclusion_tag('result.html')
def test():
a=['first','second','third']
return {'choices':a}
result.html 內容
<ul>
{% for choice in choices %}
<li> {{ choice }} </li>
{% endfor %}
</ul>
test.html內容
{% load mytags %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% test %}
</body>
</html>
view函式:
def test(request):
return render(request,'test.html')
當訪問http://127.0.0.1:8000/test/時,瀏覽器顯示:
三 分配標籤
類似於簡單標籤,但並不會輸出結果,可以使用 as 關鍵字將結果賦給一個引數。
@register.assignment_tag
def get_current_time(format_string):
return datetime.datetime.now().strftime(format_string)
{% get_current_time "%Y-%m-%d %I:%M %p" as the_time %}
<p>The time is {{ the_time }}.</p>