今天小叮當來為大家繼續(xù)分享Django干貨彼哼。主要內容有:自定義過濾器和標簽对妄。
一、關于自定義
什么是內置敢朱?什么是自定義剪菱?
前面我們學習了內置函數、內置模版拴签、內置過濾器孝常、內置標簽,對應的也有自定義函數蚓哩、自定義模版构灸、自定義過濾器、自定義標簽岸梨。
那么喜颁,什么是內置?什么是自定義呢曹阔?所謂內置半开,這里指的是Django已經幫我們寫好的函數、模版等赃份,我們直接調用即可寂拆。所謂自定義奢米,指我們需要實現的功能,Django里面并沒有現成的函數或是模版纠永,需要我們自己手動定義實現鬓长。
二、文件路徑配置
經過前面的學習渺蒿,我們知道模版存放在“templates"目錄里痢士。同樣彪薛,自定義標簽及過濾器也有自己的存放目錄”templatetags"茂装。
(1)在項目目錄中新建python package命名為common并在主目錄settings.py中進行注冊
新建
?命名
注冊
(2)在common下新建python package命名為“templatetags"
(3)在templatetags中新建python文件命名為”common_custom"
三、自定義過濾器
方式一:裝飾器注冊
(1)在新建好的common_custom文件中編寫自定義函數
#!/usr/bin/env python# -*- coding:utf-8 -*- ?__author__ = 'IT小叮當'__time__ = '2019-01-18 20:13'from django import template
#創(chuàng)建注冊器register = template.Library()
#裝飾器的方法注冊自定義過濾器@register.filter#實現首字母變大寫其余字母均小寫的功能def my_lowercap(value): ? ?return value.capitalize()
(2)在前幾次建好的template中movie主頁index模版中測試
首先加載自定義過濾器文件
之后在使用自定義過濾器
{% load common_custom %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>movie主頁</title>
</head>
<body>
我是原始的:{{ test }}<br><br>
我使用了內置lower過濾器:{{ test|lower }}<br><br>
我使用了內置capfirst過濾器:{{ test|capfirst }}<br><br>
我串聯使用了lower過濾器和capfirst過濾器:{{test|lower|capfirst }}<br><br>
我使用了小叮當自定義的my_lowercap過濾器:{{ test|my_lowercap}}<br><br></body>
</html>
在瀏覽器中查看
可見善延,雖然內置的過濾器不能直接實現“首字母變大寫少态,其余字母變小寫。”但是易遣,我們可以通過自定義過濾器的方法一步到位彼妻。
值得注意的是,使用裝飾器注冊自定義過濾器時豆茫,還可通過在裝飾器中傳參的方式侨歉,重命名自定義的過濾器名字。
#!/usr/bin/env python# -*- coding:utf-8 -*- ?__author__ = 'IT小叮當'__time__ = '2019-01-18 20:13'from django import template
#創(chuàng)建注冊器register = template.Library()
#裝飾器的方法注冊自定義過濾器@register.filter('Mystyle')
#實現首字母變大寫其余字母均小寫的功能def my_lowercap(value): ? ?return value.capitalize()
此時在模版中使用過濾器my_lowercap便會報錯
使用重命名后的過濾器Mystyle
代碼如下
我使用了小叮當自定義的my_lowercap過濾器:{{ test|Mystyle}}<br><br>
在瀏覽器中查看
方式二:函數調用的方式注冊
在common_custom中添加如下代碼:
#自定義實現cut過濾器功能def my_cut(value,arg): ? ?return value.replace(arg,'')
#函數調用的方法注冊自定義過濾器register.filter(my_cut)
在模版中使用如下
{% load common_custom %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>movie主頁</title>
</head>
<body>
我是原始的:{{ test }}<br><br>
我使用了內置cut過濾器過濾IS:{{ test|cut:'IS'}}<br><br>
我使用了小叮當自定義的cut過濾器過濾IS:{{ test|my_cut:'IS'}}<br><br>
我使用了內置cut過濾器過濾空格:{{ test|cut:'IS'}}<br><br>
我使用了小叮當自定義的cut過濾器過濾空格:{{ test|my_cut:'IS'}}<br><br></body>
</html>
在瀏覽器中查看
小結:
自定義過濾器就是一個帶有一個或兩個參數的Python 函數:
- (輸入的)變量的值 —— 不一定是字符串形式揩魂。
- 參數的值 —— 可以有一個初始值幽邓,或者完全不要這個參數
四、自定義標簽
自定義標簽分為簡單標簽和包含標簽火脉。
簡單標簽django.template.Library.simple_tag()
包含標簽django.template.Library.inclusion_tag()
tag()方法有兩個參數:
(1) 模板標記的名稱 - 字符串牵舵。 如果省略,將使用編譯函數的名稱倦挂。
(2)編譯的函數 – 一個Python函數(不要把函數名寫成字符串)
與過濾器注冊一樣畸颅,也可以將其用作裝飾器。
1.簡單標簽
(1)在"common_custom.py"中自定義簡單標簽
代碼如下:
#自定義簡單標簽輸出當前時間import datetime
@register.simple_tagdef current_time(): ? ?format_date = '%Y年%m月%d日 %H:%M:%S' ? ?return datetime.datetime.now().strftime(format_date)
(2)在templates的movie下的index模版中進行測試
{% load common_custom %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>movie主頁</title>
</head>
<body>
我是小叮當自定義的簡單標簽:{% current_time %}<br></body>
</html>
瀏覽器中查看
簡單標簽傳參--模版中傳參
模版標簽的傳參格式:”標簽名稱+空格+參數“
自定義可傳參的簡單標簽
@register.simple_tagdef current_time2(format_date): ? ?return datetime.datetime.now().strftime(format_date)
在模版中傳參
我還是小叮當自定義的簡單標簽方援,我從模版中傳參:{% current_time2 '%Y年%m月%d日 %H:%M:%S' %}<br>
到瀏覽器中查看
簡單標簽傳參--視圖函數中通過”上下文“傳參
(1)在movie的views.py中的視圖函數里通過"context"上下文傳參
def index(request,age): ? ?return render(request,'movie/index.html',
context={'format_date':'%Y年%m月%d日 %H:%M:%S',
} )
(2)在"common_custom.py"中自定義簡單標簽
@register.simple_tag(takes_context=True)
def current_time3(context): ? ?format_date=context.get('format_date')
return datetime.datetime.now().strftime(format_date)
需要注意的是没炒,通過視圖函數上下文傳參定義的簡單標簽,需要在簡單標簽裝飾器中令”takes_context=True"(takes_context默認為False)
(3)在模板中引用
1我是小叮當自定義的簡單標簽:{%?current_time?%}<br>
2我還是小叮當自定義的簡單標簽犯戏,我從模版中傳參:{%?current_time2?'%Y年%m月%d日?%H:%M:%S'?%}<br>
3我也是小叮當自定義的簡單標簽送火,我通過視圖函數context傳參:{%?current_time3?%}<br>
(4)在瀏覽器中查看
2.包含標簽
#1問題引入
(1)movie主頁視圖函數
#定義列表li=['a','b','c']
#定義字典di={'x':1,'y':2}
tup=('x','y','z')
mytest="THIS IS TEST!"#導入時間模塊import datetime
def index(request,age): ? ?return render(request,'movie/index.html',
context={'format_date':'%Y年%m月%d日 %H:%M:%S',
'strname':'我是字符串',#傳遞字符串 ? ? ? ? ? ? ? ? ? ? ? ? ? 'hello':hello,#傳遞自定義函數 ? ? ? ? ? ? ? ? ? ? ? ? ? 'xdd_say':xdd_info.say,#傳遞類方法 ? ? ? ? ? ? ? ? ? ? ? ? ? 'xdd':xdd_info,#傳遞類對象 ? ? ? ? ? ? ? ? ? ? ? ? ? 'list':li,#傳遞列表 ? ? ? ? ? ? ? ? ? ? ? ? ? 'dict':di,#傳遞字典 ? ? ? ? ? ? ? ? ? ? ? ? ? 'test':mytest,
'xdd666':None,
'num1':18,
'num2':2,
'html':'<h1>THIS IS IN HTML!</h1>',
'float':3.1415,
'now':datetime.datetime.now,
'tuple':tup,
} )
(2)movie主頁模版
{% load common_custom %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>movie主頁</title>
</head>
<body>
{% for i in list %}
<li>{{ i }}</li>
{% endfor %}
{% for i in tuple %}
<li>{{ i }}</li>
{% endfor %}
</html>
(3)瀏覽器中查看
我們發(fā)現,要實現列表list變量和元組tuple變量的顯示笛丙,for循環(huán)模版標簽幾乎一樣漾脂,不同的只是傳入的對象從list變成了tuple
為了避免代碼重復,我們可以使用包含標簽的方法胚鸯。
(4)我們在templates下movie中新建“show_tags"html文件將骨稿,重復的代碼復制到其中。
代碼如下:
{% for i in choice %}
<li>{{ i }}</li>
{% endfor %}
#2自定義包含標簽固定傳參
(1)在"common_custom.py"中自定義包含標簽
#自定義包含標簽并與重復部分的代碼綁定@register.inclusion_tag('movie/show_tags.html')
def custom_for(): ? ?test_list=['ax','ay','az']
#將固定參數test_list傳給自定義模版標簽變量choice ? ?return {'choice':test_list}
(2)在movie模版主頁使用
{% for i in list %}
<li>{{ i }}</li>
{% endfor %}
{% for i in tuple %}
<li>{{ i }}</li>
{% endfor %}
--------------------------------------<br>
我使用了小叮當自定義的包含標簽custom_for{% custom_for %}
(3)在瀏覽器中查看
#3自定義包含標簽?通過標簽自己傳參
?(1)在"common_custom.py"中自定義包含標簽
@register.inclusion_tag('movie/show_tags.html')
def custom_for2(args): ? ?return {'choice':args}
(2)在movie模版主頁使用并傳入參數list
{% for i in list %}
<li>{{ i }}</li>
{% endfor %}
{% for i in tuple %}
<li>{{ i }}</li>
{% endfor %}
--------------------------------------<br>
我使用了小叮當自定義的包含標簽custom_for{% custom_for %}
--------------------------------------<br>
我使用了小叮當自定義的包含標簽custom_for2{% custom_for2 list %}
(3)在瀏覽器中查看
#4自定義包含標簽?接受上下文傳參
(1) 在"common_custom.py"中自定義包含標簽
@register.inclusion_tag('movie/show_tags.html',takes_context=True)
def custom_for3(context): ? ?args=context.get('list')
return {'choice':args}
傳入了對應視圖函數中的list
(2)在模版中使用自定義包含標簽
{% for i in list %}
<li>{{ i }}</li>
{% endfor %}
{% for i in tuple %}
<li>{{ i }}</li>
{% endfor %}
--------------------------------------<br>
我使用了小叮當自定義的包含標簽custom_for{% custom_for %}
--------------------------------------<br>
我使用了小叮當自定義的包含標簽custom_for2{% custom_for2 list %}
--------------------------------------<br>
我使用了小叮當自定義的包含標簽custom_for3{% custom_for3 %}
(3)在瀏覽器中查看