在Python代碼中使用Django模板的最基本方式以下:html
能夠用原始的模板代碼字符串建立一個 Template 對象, Django一樣支持用指定模板文件路徑的方式來建立 Template 對象;django
調用模板對象的render方法,而且傳入一套變量context。它將返回一個基於模板的展示字符串,模板中的變量和標籤會被context值替換。windows
——————————————————————————————基本方法————————————————————————————————————瀏覽器
建立一個 Template 對象最簡單的方法就是直接實例化它。 Template 類就在 django.template 模塊中,構造函數接受一個參數,原始模板代碼。 讓咱們深刻挖掘一下 Python的解釋器看看它是怎麼工做的。框架
當你建立一個 Template 對象,模板系統在內部編譯這個模板到內部格式,並作優化,作好 渲染的準備。 若是你的模板語法有錯誤,那麼在調用 Template() 時就會拋出 TemplateSyntaxError 異常。函數
一旦你建立一個 Template 對象,你能夠用 context 來傳遞數據給它。 一個context是一系列變量和它們值的集合。優化
context在Django裏表現爲 Context 類,在 django.template 模塊裏。 她的構造函數帶有一個可選的參數: 一個字典映射變量和它們的值。 調用 Template 對象 的 render() 方法並傳遞context來填充模板。編碼
你可能首先考慮把模板保存在文件系統的某個位置並用 Python 內建的文件操做函數來讀取文件內容。 假設文件保存在 /home/djangouser/templates/mytemplate.html 中的話,代碼就會像下面這樣:spa
from django.template import Template, Context from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() # Simple way of using templates from the filesystem. # This is BAD because it doesn't account for missing files! fp = open('/home/djangouser/templates/mytemplate.html') t = Template(fp.read()) fp.close() html = t.render(Context({'current_date': now})) return HttpResponse(html)
然而,基於如下幾個緣由,該方法還算不上簡潔:debug
它沒有對文件丟失的狀況作出處理。 若是文件 mytemplate.html 不存在或者不可讀, open() 函數調用將會引起 IOError 異常。
這裏對模板文件的位置進行了硬編碼。 若是你在每一個視圖函數都用該技術,就要不斷複製這些模板的位置。 更不用說還要帶來大量的輸入工做!
它包含了大量使人生厭的重複代碼。 與其在每次加載模板時都調用 open() 、 fp.read() 和 fp.close() ,還不如作出更佳選擇。
爲了解決這些問題,咱們採用了 模板自加載 跟 模板目錄 的技巧.
——————————————————————————————合理方法————————————————————————————
模板自加載
爲了減小模板加載調用過程及模板自己的冗餘代碼,Django 提供了一種使用方便且功能強大的 API ,用於從磁盤中加載模板,
要使用此模板加載API,首先你必須將模板的保存位置告訴框架。 設置的保存文件就是咱們前一章節講述ROOT_URLCONF配置的時候提到的 settings.py。
TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. )
該設置告訴 Django 的模板加載機制在哪裏查找模板。 選擇一個目錄用於存放模板並將其添加到 TEMPLATE_DIRS 中:
最省事的方式是使用絕對路徑(即從文件系統根目錄開始的目錄路徑)。 若是想要更靈活一點並減小一些負面干擾,可利用 Django 配置文件就是 Python 代碼這一點來動態構建 TEMPLATE_DIRS 的內容,如: 例如:
import os.path TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'), )
這個例子使用了神奇的 Python 內部變量 __file__ ,該變量被自動設置爲代碼所在的 Python 模塊文件名。 `` os.path.dirname(__file__)`` 將會獲取自身所在的文件,即settings.py 所在的目錄,而後由os.path.join 這個方法將這目錄與 templates 進行鏈接。若是在windows下,它會智能地選擇正確的後向斜槓」「進行鏈接,而不是前向斜槓」/」。
完成 TEMPLATE_DIRS 設置後,下一步就是修改視圖代碼。
讓它使用 Django 模板加載功能而不是對模板路徑硬編碼。 返回 current_datetime 視圖,進行以下修改:
from django.template.loader import get_template from django.template import Context from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() t = get_template('current_datetime.html') html = t.render(Context({'current_date': now})) return HttpResponse(html)
此範例中,咱們使用了函數 django.template.loader.get_template() ,而不是手動從文件系統加載模板。 該 get_template() 函數以模板名稱爲參數,在文件系統中找出模塊的位置,打開文件並返回一個編譯好的 Template 對象。
在這個例子裏,咱們選擇的模板文件是current_datetime.html,但這個與.html後綴沒有直接的聯繫。 你能夠選擇任意後綴的任意文件,只要是符合邏輯的都行。甚至選擇沒有後綴的文件也不會有問題。
該頁面與咱們在第三章解釋過的錯誤頁面類似,只不過多了一塊調試信息區: 模板加載器過後檢查區。 該區域顯示 Django 要加載哪一個模板、每次嘗試出錯的緣由(如:文件不存在等)。 當你嘗試調試模板加載錯誤時,這些信息會很是有幫助。
接下來,在模板目錄中建立包括如下模板代碼 current_datetime.html 文件:
<html><body>It is now {{ current_date }}.</body></html>
在網頁瀏覽器中刷新該頁,你將會看到完整解析後的頁面。
——————————————————————————其餘方法————————————————————————————————————
咱們已經告訴你如何載入一個模板文件,而後用 Context渲染它,最後返回這個處理好的HttpResponse對象給用戶。 咱們已經優化了方案,使用 get_template() 方法代替繁雜的用代碼來處理模板及其路徑的工做。 但這仍然須要必定量的時間來敲出這些簡化的代碼。 這是一個廣泛存在的重複苦力勞動。Django爲此提供了一個捷徑,讓你一次性地載入某個模板文件,渲染它,而後將此做爲 HttpResponse返回。
該捷徑就是位於 django.shortcuts 模塊中名爲 render_to_response() 的函數。大多數狀況下,你會使用,除非你的老闆以代碼行數來衡量你的工做。
—————————————————————context處理器的用處原來是爲了簡化模板渲染——————————————————————
Django所以提供對 全局 context處理器的支持。 TEMPLATE_CONTEXT_PROCESSORS 指定了哪些context processors老是默認被使用。這樣就省去了每次使用 RequestContext 都指定 processors 的麻煩。
默認狀況下, TEMPLATE_CONTEXT_PROCESSORS 設置以下:
TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.auth', 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', )