W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
模板引擎是通過(guò) ?TEMPLATES
?進(jìn)行配置。這是一個(gè)配置列表,每個(gè)引擎都有一個(gè)。默認(rèn)值為空。?startproject
?命令生成的 ?settings.py
? 定義了一個(gè)更有用的值:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
# ... some options here ...
},
},
]
?BACKEND
?是實(shí)現(xiàn) Django 模板后端 API 的模板引擎類(lèi)的點(diǎn)分隔 Python 路徑。內(nèi)置的后端有 ?django.template.backends.django.DjangoTemplates
? 和 ?django.template.backends.jinja2.Jinja2
?。
由于大多數(shù)引擎都是從文件中加載模板,因此每個(gè)引擎的頂層配置都包含兩個(gè)常見(jiàn)的配置:
DIRS
?定義了目錄列表,引擎應(yīng)在其中按搜索順序查找模板源文件。APP_DIRS
?告訴引擎是否應(yīng)該在已安裝的應(yīng)用程序中尋找模板。每個(gè)后端都為應(yīng)用程序中存儲(chǔ)模板的子目錄定義了一個(gè)慣用名稱(chēng)。雖然不常見(jiàn),但可以使用不同的選項(xiàng)配置同一后端的多個(gè)實(shí)例。 在這種情況下,你應(yīng)該為每個(gè)引擎定義一個(gè)唯一的 ?NAME
?。
?OPTIONS
?包含特定于后端的配置。
?django.template.loader
? 模塊定義了兩個(gè)加載模板的函數(shù)。
此函數(shù)使用給定名稱(chēng)加載模板并返回 ?Template
?對(duì)象。
返回值的確切類(lèi)型取決于加載模板的后端。 每個(gè)后端都有自己的 ?Template
?類(lèi)。
?get_template()
? 依次嘗試每個(gè)模板引擎,直到成功為止。如果找不到模板,則會(huì)引發(fā) ?TemplateDoesNotExist
?錯(cuò)誤。如果找到模板但包含無(wú)效語(yǔ)法,則會(huì)引發(fā) ?TemplateSyntaxError
?錯(cuò)誤。
搜索和加載模板的方式取決于每個(gè)引擎的后端和配置。
如果你想把搜索限制在一個(gè)特定的模板引擎上,在 ?using
?參數(shù)中傳遞該引擎的 ?NAME
?。
?select_template()
?就像 ?get_template()
?,不同的是,它接受一個(gè)模板名稱(chēng)的列表。它按順序嘗試每個(gè)名字,并返回第一個(gè)存在的模板。
如果加載模板失敗,則可能會(huì)引發(fā)在 ?django.template
? 中定義的以下兩個(gè)異常:
當(dāng)找不到模板時(shí)引發(fā)此異常。
backend
?:產(chǎn)生異常的模板后端實(shí)例。tried
?:查找模板時(shí)嘗試過(guò)的來(lái)源列表。它的格式為包含 (origin, status) 的元組列表,其中 origin 是一個(gè) 類(lèi) origin 對(duì)象而 status 是一個(gè)說(shuō)明找不到模板原因的字符串。chain
?:嘗試加載模板時(shí)引發(fā)的一系列中間 TemplateDoesNotExist 異常列表。這由函數(shù)使用,例如:get_template(),這些函數(shù)嘗試從多個(gè)引擎加載給定的模板。
當(dāng)找到模板但包含錯(cuò)誤時(shí),將引發(fā)此異常。
由 ?get_template()
? 和 ?select_template()
? 返回的 ?Template
?對(duì)象必須提供具有以下簽名的?render()
?方法:
context
?,則必須是 ?dict
?。如果未提供,則引擎將使用空上下文渲染模板。request
?,它必須是 ?HttpRequest
?。同時(shí)引擎必須使它和 CSRF 令牌在模板中可用。如何實(shí)現(xiàn)這一點(diǎn)由每個(gè)后端決定。下面是一個(gè)搜索算法的例子。在這個(gè)例子中 ?TEMPLATES
?設(shè)置為:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
'/home/html/example.com',
'/home/html/default',
],
},
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [
'/home/html/jinja2',
],
},
]
如果你調(diào)用 ?get_template('story_detail.html')
?,以下是 Django 將按順序查找的文件:
/home/html/example.com/story_detail.html
? (?django
?引擎)/home/html/default/story_detail.html
? (?django
?引擎)/home/html/jinja2/story_detail.html
? (?jinja2
?引擎)如果你調(diào)用 ?select_template(['story_253_detail.html', 'story_detail.html'])
?,Django 將尋找以下內(nèi)容:
/home/html/example.com/story_253_detail.html
?(?django
?引擎)/home/html/default/story_253_detail.html
? (?django
?引擎)/home/html/jinja2/story_253_detail.html
? (?jinja2
?引擎)/home/html/example.com/story_detail.html
? (?django
?引擎)/home/html/default/story_detail.html
? (?django
?引擎)/home/html/jinja2/story_detail.html
? (?jinja2
?引擎)當(dāng) Django 發(fā)現(xiàn)一個(gè)模板存在時(shí),它就會(huì)停止尋找。
提示:你可以使用 ?select_template()
? 靈活的加載模板。例如,如果你寫(xiě)了一個(gè)新聞故事,并希望一些故事有自定義模板,使用類(lèi)似 ?select_template(['story_%s_detail.html' % story.id, 'story_detail.html'])
? 。這將允許你為單個(gè)故事使用自定義模板,為沒(méi)有自定義模板的故事使用備用模板。
最好是在每個(gè)包含模板的目錄內(nèi)的子目錄中組織模板。慣例是為每個(gè) Django 應(yīng)用程序創(chuàng)建一個(gè)子目錄,根據(jù)需要在這些子目錄中包含子目錄。
要加載子目錄中的模板,請(qǐng)使用斜杠,如下所示:
get_template('news/story_detail.html')
使用與上述相同的 ?TEMPLATES
?選項(xiàng),這將嘗試加載以下模板:
/home/html/example.com/news/story_detail.html
? (?django
?引擎)/home/html/default/news/story_detail.html
? (?django
?引擎)/home/html/jinja2/news/story_detail.html
? (?jinja2
?引擎)此外,為了減少加載和渲染模板的重復(fù)性,Django 提供了一個(gè)自動(dòng)處理的快捷函數(shù)。
?render_to_string()
? 加載一個(gè)模板 ?get_template()
?,并立即調(diào)用它的? render()
?方法。它需要下面的參數(shù)。
template_name
?:加載和呈現(xiàn)模板的名稱(chēng)。如果是模板名稱(chēng)列表,Django 使用 select_template() ,而不是 get_template() 找到模板。context
?:?dict
?用作模板的渲染上下文。request
?:可選項(xiàng) ?HttpRequest
?在模板的渲染過(guò)程中可用。using
?:可選的模板引擎 ?NAME
?。對(duì)模板的搜索將限于該引擎。使用實(shí)例:
from django.template.loader import render_to_string
rendered = render_to_string('my_template.html', {'foo': 'bar'})
還可以用 ?render()
? 快捷函數(shù),它調(diào)用 ?render_to_string()
? ,并將結(jié)果提供給 ?HttpResponse
?,適合從視圖返回。
最后,您可以直接使用配置好的引擎:
模板引擎可在 ?django.template.engines
? 中使用:
from django.template import engines
django_engine = engines['django']
template = django_engine.from_string("Hello {{ name }}!")
在這個(gè)例子中,查找關(guān)鍵字“django”是引擎的 ?NAME
?。
設(shè)置 ?BACKEND
?為 ?django.template.backends.django.DjangoTemplates
?,以配置 Django 模板引擎。
當(dāng) ?APP_DIRS
?為 ?True
?時(shí),?DjangoTemplates
?引擎會(huì)在已安裝應(yīng)用程序的 ?templates
?子目錄中尋找模板。這個(gè)通用名稱(chēng)是為了向后兼容而保留的。
?DjangoTemplates
引擎接受以下 ?OPTIONS
?:
?autoescape
?:一個(gè)布爾值,控制是否啟用 HTML 自動(dòng)轉(zhuǎn)義。默認(rèn)為 ?True
?。只有當(dāng)你渲染非 HTML 模板時(shí),才將其設(shè)置為 ?False
?!
?context_processors
?:當(dāng)模板被請(qǐng)求渲染時(shí),用于填充上下文的可調(diào)用項(xiàng)的點(diǎn)分隔 Python 路徑列表。這些可調(diào)用的對(duì)象以一個(gè)請(qǐng)求對(duì)象作為參數(shù),并返回一個(gè) ?dict
?的項(xiàng)目,這些項(xiàng)目將被合并到上下文中。默認(rèn)為空列表。
?debug
?:開(kāi)啟/關(guān)閉模板調(diào)試模式的布爾值。如果是 ?True
?,錯(cuò)誤頁(yè)面將顯示模板渲染過(guò)程中出現(xiàn)的任何異常的詳細(xì)報(bào)告。該報(bào)告包含模板的相關(guān)片段,并突出顯示相應(yīng)的行。
默認(rèn)為 ?DEBUG
?配置的值。
?loaders
?:模板加載器類(lèi)的點(diǎn)分隔 Python 路徑列表。每個(gè) ?Loader
?類(lèi)都知道如何從特定源導(dǎo)入模板??梢赃x擇使用元組來(lái)代替字符串。元組中的第一項(xiàng)應(yīng)該是 ?Loader
?類(lèi)名,隨后的項(xiàng)在初始化期間傳遞給 ?Loader
?。默認(rèn)值取決于 ?DIRS
?和 ?APP_DIRS
?的值。
?string_if_invalid
?:模板系統(tǒng)對(duì)無(wú)效變量(如拼寫(xiě)錯(cuò)誤)應(yīng)將此字符串輸出。默認(rèn)為空字符串。
?file_charset
?:用于讀取磁盤(pán)上模板文件的字符集。默認(rèn)為 utf-8。
?libraries
?:模板標(biāo)簽?zāi)K的標(biāo)簽字典和點(diǎn)分隔 Python 路徑,用于向模板引擎注冊(cè)。 這可用于添加新庫(kù)或?yàn)楝F(xiàn)有庫(kù)提供替代標(biāo)簽。例如:
OPTIONS={
'libraries': {
'myapp_tags': 'path.to.myapp.tags',
'admin.urls': 'django.contrib.admin.templatetags.admin_urls',
},
}
可以通過(guò)將相應(yīng)的字典鍵傳遞到 ?{% load %}
? 標(biāo)簽來(lái)加載庫(kù)。
?builtins
?:要添加的 內(nèi)置模板標(biāo)簽和過(guò)濾器 的點(diǎn)分隔 Python 路徑列表。例如:
OPTIONS={
'builtins': ['myapp.builtins'],
}
可以使用內(nèi)置庫(kù)中的標(biāo)簽和過(guò)濾器,而不需要先調(diào)用 ?{% load %}
? 標(biāo)簽。
需要安裝 Jinja2:
...\> py -m pip install Jinja2
設(shè)置 ?BACKEND
?為 django.template.backends.jinja2.Jinja2
?以配置一個(gè) Jinja2 引擎。
當(dāng) ?APP_DIRS
?為 ?True
?時(shí),Jinja2 引擎會(huì)在安裝的應(yīng)用程序的 jinja2 子目錄中查找模板。
?OPTIONS
?中最重要的條目是 ?environment
?。它是一個(gè)點(diǎn)分隔 Python 路徑,指向一個(gè)返回 Jinja2 環(huán)境的可調(diào)用對(duì)象。默認(rèn)為 ?jinja2.Environment
?。Django 調(diào)用該可調(diào)用對(duì)象并傳遞其他選項(xiàng)作為關(guān)鍵字參數(shù)。此外,Django 為一些選項(xiàng)添加了不同于 Jinja2 的默認(rèn)值。
autoescape
?:?True
?loader
?:為 ?DIRS
?和 ?APP_DIRS
?配置的加載器auto_reload
?:?settings.DEBUG
?undefined
?:?DebugUndefined if settings.DEBUG else Undefined
?Jinja2 引擎也接受以下 ?OPTIONS
?:
?context_processors
?:當(dāng)模板被請(qǐng)求渲染時(shí),用于填充上下文的可調(diào)用項(xiàng)的點(diǎn)分隔 Python 路徑列表。這些可調(diào)用的對(duì)象以一個(gè)請(qǐng)求對(duì)象作為參數(shù),并返回一個(gè) ?dict
?的項(xiàng)目,這些項(xiàng)目將被合并到上下文中。默認(rèn)為空列表
上下文處理器在 Django 模板中很有用,因?yàn)?Django 模板不支持調(diào)用帶參數(shù)的函數(shù)。由于 Jinja2 沒(méi)有此限制,因此建議將你要用作上下文處理器的函數(shù)放在模板的全局變量 ?jinja2.Environment
? 中使用,如下所述。然后你可以在模板中調(diào)用該函數(shù)。
{{ function(request) }}
有些 Django 模板的上下文處理器會(huì)返回一個(gè)固定的值。對(duì)于 Jinja2 模板,不需要這一層間接操作,因?yàn)槟梢灾苯釉??jinja2.Environment
? 中添加常量。
最初為 Jinja2 增加上下文處理器的用例涉及:
除非滿(mǎn)足所有這些條件,否則將函數(shù)傳遞給模板更符合 Jinja2 的設(shè)計(jì)。
默認(rèn)配置被有意地保持為最低。如果一個(gè)模板被請(qǐng)求渲染(例如,當(dāng)使用 ?render()
?),Jinja2 后端會(huì)在上下文中添加 ?request
?,?csrf_input
?和 ?csrf_token
?。除此之外,此后端不會(huì)創(chuàng)建 Django 風(fēng)格的環(huán)境。 它不知道 Django 過(guò)濾器和標(biāo)簽。 為了使用 Django 特有的 API,你必須將它們配置到環(huán)境中。
例如,您可以使用以下內(nèi)容創(chuàng)建 ?myproject/jinja2.py
? :
from django.templatetags.static import static
from django.urls import reverse
from jinja2 import Environment
def environment(**options):
env = Environment(**options)
env.globals.update({
'static': static,
'url': reverse,
})
return env
并將 ?environment
? 選項(xiàng)設(shè)置為 ?myproject.jinja2.environment
?
這樣你就可以在 Jinja2 模板中使用以下構(gòu)造:
<img src="{{ static('path/to/company-logo.png') }}" alt="Company Logo">
<a href="{{ url('admin:index') }}">Administration</a>
Django 模板語(yǔ)言和 Jinja2 中都存在標(biāo)簽和過(guò)濾器的概念,但使用方式不同。由于 Jinja2 支持在模板中向可調(diào)用對(duì)象傳遞參數(shù),所以很多在 Django 模板中需要模板標(biāo)簽或過(guò)濾器的功能都可以通過(guò)在 Jinja2 模板中調(diào)用函數(shù)來(lái)實(shí)現(xiàn),如上例所示。Jinja2 的全局命名空間消除了對(duì)模板上下文處理器的需求。Django 模板語(yǔ)言并沒(méi)有與 Jinja2 測(cè)試相對(duì)應(yīng)的功能。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: