Django模板語言

知識點(diǎn):

  1. 代碼布局
  2. 編寫自定義模板過濾器
  3. 簡單標(biāo)簽
  4. 包含標(biāo)簽
  5. 分配標(biāo)簽
  6. 靜態(tài)文件加載

為了解決應(yīng)用中展示邏輯的需求,Django的模板語言提供了各式各樣的built-in tags and filters。 然而,你或許會發(fā)現(xiàn)模板內(nèi)建的這些工具集合不一定能全部滿足你的功能需要。 您可以通過使用Python定義自定義標(biāo)簽和過濾器來擴(kuò)展模板引擎,然后使用{% load %}標(biāo)簽。

代碼布局

指定自定義模板標(biāo)簽和過濾器的最常見的地方在Django應(yīng)用程序中。

當(dāng)將Django應(yīng)用程序添加到INSTALLED_APPS中時(shí),在下面描述的常規(guī)位置中定義的任何標(biāo)簽將自動在模板中加載。

這個(gè)應(yīng)用應(yīng)該包含一個(gè)templatetags 目錄,和views.py、models.py等文件處于同一級別目錄下。 如果目錄不存在則創(chuàng)建它——不要忘記創(chuàng)建init.py 文件以使得該目錄可以作為Python 的包。

你的自定義的標(biāo)簽和過濾器將放在templatetags 目錄下的一個(gè)模塊里。 這個(gè)模塊的名字是你稍后將要載入標(biāo)簽時(shí)使用的,所以要謹(jǐn)慎的選擇名字以防與其他應(yīng)用下的自定義標(biāo)簽和過濾器名字沖突。

例如,你的自定義標(biāo)簽/過濾器在一個(gè)名為common_extras.py的文件中,那么你的app目錄結(jié)構(gòu)看起來應(yīng)該是這樣的:

common/
    __init__.py
    models.py
    templatetags/
        __init__.py
        common_extras.py
    views.py

在模板中像如下這樣使用:

{% load common_extras %}

為了讓{% load %}標(biāo)簽工作,包含自定義標(biāo)簽的應(yīng)用必須在INSTALLED_APPS中。在 templatetags 包中放多少個(gè)模塊沒有限制。 只需要記住{% load %} 聲明將會載入給定模塊名中的標(biāo)簽/過濾器,而不是應(yīng)用的名稱。

為了成為一個(gè)可用的標(biāo)簽庫,這個(gè)模塊必須包含一個(gè)名為 register的變量,它是template.Library 的一個(gè)實(shí)例,所有的標(biāo)簽和過濾器都是在其中注冊的。 所以把如下的內(nèi)容放在你的模塊的頂部:

from django import template

register = template.Library()

編寫自定義模板過濾器

自定義過濾器就是一個(gè)帶有一個(gè)或兩個(gè)參數(shù)的Python 函數(shù):

  • (輸入的)變量的值 —— 不一定是字符串形式。
  • 參數(shù)的值 —— 可以有一個(gè)初始值,或者完全不要這個(gè)參數(shù)。

例如,在{{ var|foo:"bar" }}中,foo過濾器應(yīng)當(dāng)傳入變量var和參數(shù) "bar"。

定義過濾器的例子:

def mycut(value, arg):
    return value.replace(arg, '')

這個(gè)過濾器的使用:

{{ somevariable|mycut:"0" }}

大多數(shù)過濾器沒有參數(shù)。 在這種情況下,你的函數(shù)不帶這個(gè)參數(shù)即可。 例如:

def mylower(value):
    return value.lower()

注冊自定義過濾器

django.template.Library.filter()

讓自定義的過濾器在Django模板語言中可用,就需要把它注冊為你的 Library實(shí)例:

register.filter('mycut', mycut)
register.filter('mylower', mylower)

Library.filter()方法需要兩個(gè)參數(shù):

  1. 過濾器的名稱(一個(gè)字符串對象)
  2. 編譯的函數(shù) – 一個(gè)Python函數(shù)(不要把函數(shù)名寫成字符串)

還可以把register.filter()用作裝飾器:

@register.filter(name='mycut')
def mycut(value, arg):
    return value.replace(arg, '')

@register.filter
def mylower(value):
    return value.lower()

沒有聲明 name 參數(shù),Django將使用函數(shù)名作為過濾器的名字。

如果你正在編寫一個(gè)只希望用一個(gè)字符串來作為第一個(gè)參數(shù)的模板過濾器,你應(yīng)當(dāng)使用stringfilter裝飾器。 這將在對象被傳入你的函數(shù)之前把這個(gè)對象轉(zhuǎn)換成它的字符串值:

from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
@register.filter
@stringfilter    #注釋掉此句傳遞int類型會報(bào)錯(cuò)
def mylower(value):
    return value.lower()

編寫自定義模板標(biāo)簽

簡單標(biāo)簽django.template.Library.simple_tag()

許多模板標(biāo)簽需要許多參數(shù) - 字符串或模板變量,并且僅在基于輸入?yún)?shù)和一些外部信息進(jìn)行一些處理后返回結(jié)果。 例如,current_time 標(biāo)簽可能接受一個(gè)格式字符串,并返回與之對應(yīng)的格式化后的時(shí)間。

為了簡單化這些類型標(biāo)簽的創(chuàng)建,Django 提供一個(gè)輔助函數(shù)simple_tag。 這個(gè)函數(shù)是django.template.Library 的一個(gè)方法,接受一個(gè)任意數(shù)目的參數(shù)的函數(shù),將其包裝在一個(gè)render 函數(shù)和上面提到的其他必要部分中,并在模板系統(tǒng)中注冊它。

注冊標(biāo)簽,向模塊的Library實(shí)例注冊代碼

register.tag('current_time', do_current_time)

tag()方法有兩個(gè)參數(shù):

  1. 模板標(biāo)記的名稱 - 字符串。 如果省略,將使用編譯函數(shù)的名稱。
  2. 編譯的函數(shù) – 一個(gè)Python函數(shù)(不要把函數(shù)名寫成字符串)

與過濾器注冊一樣,也可以將其用作裝飾器。

例子:

# hello_django/music/templatetages/common_tag.py

import datetime
from django import template
register = template.Library()

@register.simple_tag
def current_time(format_string):
    return datetime.datetime.now().strftime(format_string)

如果你的模板標(biāo)簽需要訪問當(dāng)前上下文,你可以在注冊標(biāo)簽時(shí)使用takes_context 參數(shù)︰

# hello_django/music/templatetages/common_tag.py

@register.simple_tag(takes_context=True)
def current_time(context ):
    tm = context['format_string']
    return datetime.datetime.now().strftime(tm)
    
# 這里的tm是從視圖函數(shù)context中傳進(jìn)來的。

包含標(biāo)簽django.template.Library.inclusion_tag()

另一種常見類型的模板標(biāo)簽是通過渲染另外一個(gè)模板來顯示一些數(shù)據(jù)。這些類型的標(biāo)簽被稱為"Inclusion 標(biāo)簽"。

例子:

# hello_django/music/templatetages/common_tag.py

@register.inclusion_tag('music/show_tag.html')
def show_results():
    li = ['python','java','c++']
    return {'choices':li}

{# hello_django/music/templates/show_tag.html#}

<ul>
    {% for i in choices %}
        <li>{{ i }}</li>
    {% endfor %}
</ul>

分配標(biāo)簽

為了簡單化設(shè)置上下文中變量的標(biāo)簽的創(chuàng)建,Django 提供一個(gè)輔助函數(shù)assignment_tag。 除了將標(biāo)簽的結(jié)果存儲在指定的上下文變量中,而不是直接輸出,該函數(shù)的工作方式與simple_tag()相同。

我們之前的current_time 函數(shù)從而可以這樣寫︰

# hello_django/music/templatetages/common_tag

@register.assignment_tag
def current_time_1(format_string):
    return datetime.datetime.now().strftime(format_string)

然后你可以使用as 參數(shù)后面跟隨變量的名稱將結(jié)果存儲在模板變量中,并將它輸出到你覺得合適的地方︰

{% current_time_1 '%Y-%m-%d %H:%M:%P' as ctime %}
The time is {{ ctime }}

模板加載靜態(tài)文件

1、在settings中,找到INSTALLED_APPS,然后確保有django.contrib.staticfiles。

2、在settings中,選擇性的設(shè)置STATIC_ROOT和STATIC_URL以及STATICFILES_DIRS

3、STATICFILES_DIRS可以設(shè)置絕對路徑也可以是相對路徑。同templates

4、默認(rèn)STATICFILES_FINDERS會到安裝了的app下面的static文件夾找靜態(tài)文件。

5、在模板中,使用static標(biāo)簽加載靜態(tài)文件。注意路徑!

例子:

我們在app下面創(chuàng)建一個(gè)static的目錄,在目錄中添加三種靜態(tài)文件:

# hello_djagngo/music/static/myjs.js
alert('hahahaha');

# --------------------------------

# hello_djagngo/music/static/mystyle.css
body{
    background: skyblue;
}
#---------------------------------

# hello_djagngo/music/static/myimage.jpg
##存入圖片

靜態(tài)文件創(chuàng)建好了之后就可以在模板里面加載靜態(tài)文件。

{# hello_django/music/templates/index.html#}

    <link rel="stylesheet" href="{% static 'mystyle.css' %}">
    <script src="{% static 'myjs.js' %}"></script>
    圖片:
    <img src="{% static 'myimage.jpg' %}" alt=""/>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容