1. 程式人生 > >django 2.1官方文件翻譯-模板(進行中)

django 2.1官方文件翻譯-模板(進行中)

django的官方文件在transifex上翻譯,本來想貢獻一下,結果發現那個介面實在是受不了。自己翻吧

模板
作為一個Web框架,Django需要一種動態生成HTML的便捷方式。最常見的方法是使用模板。模板包含HTML輸出的靜態部分以及能插入動態內容的一些特殊語法。有關使用模板建立HTML頁面的例項,請參閱教程3。

Django專案可以配置一個或多個模板引擎(甚至你可以不使用模板從零開始建立HTML)。Django有一個自己的內建模板系統,Django template language(DTL),或者你可以使用一個流行的模板系統Jinja2來替換它。也可以使用從第三方獲得的其他模板。

無論後端如何處理,Django定義了一個標準API,用於載入和渲染模板。載入由兩步組成,1.查詢給定的識別符號。2.預處理,把它編譯成一個記憶體中的形式。渲染意味著使用上下文資料插入模板並返回結果字串。

DTL是Django自己的模板系統。直到Django 1.8,它一直是唯一可用的內建選項。它是一個很好的模板庫,儘管它有點僵硬並且具有一些自己的特性。如果您沒有特殊的理由用另一個模板,那就應該用DTL,尤其是在您編寫可插拔應用程式並打算分發模板時。Django的contrib模組的apps已經包含了模板(如django.contrib.admin使用了DTL)。

由於歷史原因,模板引擎的通用支援和Django模板語言的實現都存在於django.template 模組中。

警告

使用不受信任的作者建立的模板並不安全。例如,站點不應允許使用者提供自己的模板,因為模板作者可能執行諸如執行XSS攻擊、訪問可能包含敏感資訊的模板變數屬性之類的操作。

模板引擎的支援
配置
模板引擎可以使用settings中的TEMPLATES來指定。這是一個配置列表,列表的每一項對應一個引擎。預設是空的。startproject生成的 settings.py產生一個有用的值:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            # ... some options here ...
        },
    },
]

BACKEND是一個用.分割的python路徑,描述了模板引擎類所在的位置,這個類提供了Django的模板backend API。內建的backend有 django.template.backends.django.DjangoTemplates和django.template.backends.jinja2.Jinja2。
由於大多數引擎從檔案載入模板,因此每個引擎的頂級配置包含兩個常用設定:

  • DIRS: 定義一個列表存放目錄,引擎應按順序從中查詢模板原始檔。
  • APP_DIRS:告訴引擎是否應該在已安裝的應用程式資料夾中查詢模板。app該為每個backend都在自己目錄下建立一個子資料夾存放模板。

雖然不常見,但同一模板backend可以搞幾個不同的例項。在這種情況下,應該為每個例項新建一個列表項。

OPTIONS 包含backend-specific的設定。

使用方法
django.template.loader模組定義了載入模板的兩個函式
get_template(template_name,using = None)
此函式使用給定的名稱載入模板並返回一個 Template物件。

返回值的確切型別取決於使用的backend。每個backend都有自己的Template類。

get_template()按順序嘗試每個模板引擎,直到成功。如果找不到模板,則會引起一個 TemplateDoesNotExist異常。如果找到模板但其中包含無效語法,則會引起一個 TemplateSyntaxError異常。

如何搜尋和載入模板取決於每個引擎自己的backend和配置。

如果你要使用特定的模板引擎,請在using引數中傳遞引擎NAME。

select_template(template_name_list, using=None)
select_template()和get_template()差不多,但是它接受一個模板名稱的列表。它按順序嘗試每個名稱並返回能找到的第一個模板。

如果載入模板失敗,可能引起django.template中定義的兩個異常 :
exception TemplateDoesNotExist(msg, tried=None, backend=None, chain=None)
無法找到模板時引發此異常。它接受以下可選引數,用於在除錯頁面上填充template postmortem:

backend
發生異常的模板後端例項。
tried
查詢模板時嘗試的源位置列表。被格式化為一個列表,每個列表項為包含(origin, status)的元組,其中origin是origin-like的物件,status 是一個描述了為什麼沒找到模板的字串。
chain
TemplateDoesNotExist 嘗試載入模板時引發的中間異常列表。這是給一些函式比如get_template用的,當get_template嘗試從多個引擎載入給定模板時用的到。

/*
譯註:可以嘗試一下load一個不存在的模板名,會發現template postmortem塊的資訊

Template-loader postmortem
Django tried loading these templates, in this order:

Using engine django:

django.template.loaders.filesystem.Loader: /home/songyf/Desktop/auth/templates/indx.html (Source does not exist)
django.template.loaders.app_directories.Loader: /usr/local/lib/python3.6/dist-packages/django/contrib/admin/templates/indx.html (Source does not exist)
django.template.loaders.app_directories.Loader: /usr/local/lib/python3.6/dist-packages/django/contrib/auth/templates/indx.html (Source does not exist)
chain	[TemplateDoesNotExist('indx.html',)]
engine	<django.template.backends.django.DjangoTemplates object at 0x7f8de08fa438>
engines	[<django.template.backends.django.DjangoTemplates object at 0x7f8de08fa438>]
template_name	'indx.html'
using	None

*/

異常 TemplateSyntaxError(msg)
找到模板但包含錯誤時會引發此異常。
返回的Template物件必須接著使用一個render()方法:
Template.render(context = None,request = None)
在給定的上下文中呈現此模板。
context必須是一個dict,如果沒提供,引擎會用一個空的上下文渲染模板。
request必須是一個HttpRequest。然後引擎必須在模板中提供它以及CSRF令牌。如何實現這一目標取決於不同的backend。

展示搜尋演算法的一個例子。比如 TEMPLATES設定為:

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',
        ],
    },
]

如果你呼叫 get_template(‘story_detail.html’), Django會這麼尋找:

  • /home/html/example.com/story_detail.html (‘django’ engine)
  • /home/html/default/story_detail.html (‘django’ engine)
  • /home/html/jinja2/story_detail.html (‘jinja2’ engine)

如果你呼叫select_template([‘story_253_detail.html’, ‘story_detail.html’]), Django會這麼找:

  • /home/html/example.com/story_253_detail.html (‘django’ engine)
  • /home/html/default/story_253_detail.html (‘django’ engine)
  • /home/html/jinja2/story_253_detail.html (‘jinja2’ engine)
  • /home/html/example.com/story_detail.html (‘django’ engine)
  • /home/html/default/story_detail.html (‘django’ engine)
  • /home/html/jinja2/story_detail.html (‘jinja2’ engine)

當Django找到存在的模板時,它會停止查詢。

tips:
您可以使用select_template()進行更靈活的模板載入。例如,如果您撰寫了新聞報道並希望某些故事具有自定義的模板,請使用類似這樣的函式:select_template([‘story_%s_detail.html’ % story.id, ‘story_detail.html’]) 。這將允許您為單個故事使用自定義模板,併為沒有自定義模板的故事提供後備模板。

儘可能在每個包含模板的資料夾中用一個子資料夾組織模板 。慣例是為每個Django應用程式建立一個子目錄,並根據需要在這些子目錄中包含子目錄。

這樣做是為了你自己好。將所有模板儲存在根目錄會變得很混亂。

要載入子目錄中的模板,只需使用斜槓,如下所示:

get_template('news/story_detail.html')