template

D:\workspace\template1\template1\settings.py
D:\workspace\template1\template1
D:\workspace\template1html

from django.template import Template, Context程序員

若是使用的是 Windows 平臺,請包含驅動器符號並使用Unix風格的斜槓(/)而不是反斜槓(\)sql


項目下新建templates文件夾專門存放template
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/')數據庫

from django.shortcuts import render_to_response
import datetimedjango

def current_datetime(request):
now = datetime.datetime.now()
return render_to_response('current_datetime.html', {'current_date': now})app

若是不提供第二個參數, render_to_response() 使用一個空字典。ide


若是你是個喜歡偷懶的程序員並想讓代碼看起來更加簡明,能夠利用 Python 的內建函數 locals() 。它返回的字典對全部局部變量的名稱與值進行映射。 所以,前面的視圖能夠重寫成下面這個樣子:
def current_datetime(request):
current_date = datetime.datetime.now()
return render_to_response('current_datetime.html', locals())
在此,咱們沒有像以前那樣手工指定 context 字典,而是傳入了 locals() 的值,它囊括了函數執行到該時間點時所定義的一切變量。 所以,咱們將 now 變量重命名爲 current_date ,由於那纔是模板所預期的變量名稱。 在本例中, locals() 並無帶來多 大 的改進,可是若是有多個模板變量要界定而你又想偷懶,這種技術能夠減小一些鍵盤輸入。
使用 locals() 時要注意是它將包括 全部 的局部變量,它們可能比你想讓模板訪問的要多。 在前例中, locals() 還包含了 request 。對此如何取捨取決你的應用程序。函數


把全部的模板都存放在一個目錄下可能會讓事情變得難以掌控。 你可能會考慮把模板存放在你模板目錄的子目錄中,這很是好。 事實上,咱們推薦這樣作;一些Django的高級特性(例如將在第十一章講到的通用視圖系統)的缺省約定就是指望使用這種模板佈局。
把模板存放於模板目錄的子目錄中是件很輕鬆的事情。 只需在調用 get_template() 時,把子目錄名和一條斜槓添加到模板名稱以前,如:
t = get_template('dateapp/current_datetime.html')
因爲 render_to_response() 只是對 get_template() 的簡單封裝, 你能夠對 render_to_response() 的第一個參數作相同處理。
return render_to_response('dateapp/current_datetime.html', {'current_date': now})
對子目錄樹的深度沒有限制,你想要多少層均可以。 只要你喜歡,用多少層的子目錄都無所謂。
注意
Windows用戶必須使用斜槓而不是反斜槓。 get_template() 假定的是 Unix 風格的文件名符號約定。佈局

'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',測試


def auth(request):
"""
Returns context variables required by apps that use Django's authentication
system.

If there is no 'user' attribute in the request, uses AnonymousUser (from
django.contrib.auth).
"""
if hasattr(request, 'user'):
user = request.user
else:
from django.contrib.auth.models import AnonymousUser
user = AnonymousUser()

return {
'user': user,
'perms': PermWrapper(user),
}


def messages(request):
"""
Returns a lazy 'messages' context variable.
"""
return {
'messages': get_messages(request),
'DEFAULT_MESSAGE_LEVELS': DEFAULT_LEVELS,
}

def get_messages(request):
"""
Returns the message storage on the request if it exists, otherwise returns
an empty list.
"""
if hasattr(request, '_messages'):
return request._messages
else:
return []


def request(request):
return {'request': request}


RequestContext和Context處理器
你須要一段context來解析模板。 通常狀況下,這是一個 django.template.Context 的實例,不過在Django中還能夠用一個特殊的子類, django.template.RequestContext ,這個用起來稍微有些不一樣。 RequestContext 默認地在模板context中加入了一些變量,如 HttpRequest 對象或當前登陸用戶的相關信息。
當你不想在一系例模板中都明確指定一些相同的變量時,你應該使用 RequestContext 。 例如,考慮這兩個視圖:
from django.template import loader, Context

def view_1(request):
# ...
t = loader.get_template('template1.html')
c = Context({
'app': 'My app',
'user': request.user,
'ip_address': request.META['REMOTE_ADDR'],
'message': 'I am view 1.'
})
return t.render(c)

def view_2(request):
# ...
t = loader.get_template('template2.html')
c = Context({
'app': 'My app',
'user': request.user,
'ip_address': request.META['REMOTE_ADDR'],
'message': 'I am the second view.'
})
return t.render(c)
(注意,在這些例子中,咱們故意 不 使用 render_to_response() 這個快捷方法,而選擇手動載入模板,手動構造context對象而後渲染模板。 是爲了可以清晰的說明全部步驟。)
每一個視圖都給模板傳入了三個相同的變量:app、user和ip_address。 若是咱們把這些冗餘去掉會不會更好?
建立 RequestContext 和 context處理器 就是爲了解決這個問題。 Context處理器容許你設置一些變量,它們會在每一個context中自動被設置好,而沒必要每次調用 render_to_response() 時都指定。 要點就是,當你渲染模板時,你要用 RequestContext 而不是 Context 。
最直接的作法是用context處理器來建立一些處理器並傳遞給 RequestContext 。上面的例子能夠用context processors改寫以下:
from django.template import loader, RequestContext

def custom_proc(request):
"A context processor that provides 'app', 'user' and 'ip_address'."
return {
'app': 'My app',
'user': request.user,
'ip_address': request.META['REMOTE_ADDR']
}

def view_1(request):
# ...
t = loader.get_template('template1.html')
c = RequestContext(request, {'message': 'I am view 1.'},
processors=[custom_proc])
return t.render(c)

def view_2(request):
# ...
t = loader.get_template('template2.html')
c = RequestContext(request, {'message': 'I am the second view.'},
processors=[custom_proc])
return t.render(c)
咱們來通讀一下代碼:
首先,咱們定義一個函數 custom_proc 。這是一個context處理器,它接收一個 HttpRequest 對象,而後返回一個字典,這個字典中包含了能夠在模板context中使用的變量。 它就作了這麼多。
咱們在這兩個視圖函數中用 RequestContext 代替了 Context 。在context對象的構建上有兩個不一樣點。一, RequestContext 的第一個參數須要傳遞一個 HttpRequest 對象,就是傳遞給視圖函數的第一個參數( request )。二, RequestContext 有一個可選的參數 processors ,這是一個包含context處理器函數的列表或者元組。 在這裏,咱們傳遞了咱們以前定義的處理器函數 curstom_proc 。
每一個視圖的context結構裏再也不包含 app 、 user 、 ip_address 等變量,由於這些由 custom_proc 函數提供了。
每一個視圖 仍然 具備很大的靈活性,能夠引入咱們須要的任何模板變量。 在這個例子中, message 模板變量在每一個視圖中都不同。
在第四章,咱們介紹了 render_to_response() 這個快捷方式,它能夠簡化調用 loader.get_template() ,而後建立一個 Context 對象,最後再調用模板對象的 render()過程。 爲了講解context處理器底層是如何工做的,在上面的例子中咱們沒有使用 render_to_response() 。可是建議選擇 render_to_response() 做爲context的處理器。這就須要用到context_instance參數:
from django.shortcuts import render_to_response
from django.template import RequestContext

def custom_proc(request):
"A context processor that provides 'app', 'user' and 'ip_address'."
return {
'app': 'My app',
'user': request.user,
'ip_address': request.META['REMOTE_ADDR']
}

def view_1(request):
# ...
return render_to_response('template1.html',
{'message': 'I am view 1.'},
context_instance=RequestContext(request, processors=[custom_proc]))

def view_2(request):
# ...
return render_to_response('template2.html',
{'message': 'I am the second view.'},
context_instance=RequestContext(request, processors=[custom_proc]))
在這,咱們將每一個視圖的模板渲染代碼寫成了一個單行。
雖然這是一種改進,可是,請考慮一下這段代碼的簡潔性,咱們如今不得不認可的是在 另外 一方面有些過度了。 咱們以代碼冗餘(在 processors 調用中)的代價消除了數據上的冗餘(咱們的模板變量)。 因爲你不得不一直鍵入 processors ,因此使用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',
)
這個設置項是一個可調用函數的元組,其中的每一個函數使用了和上文中咱們的 custom_proc 相同的接口,它們以request對象做爲參數,返回一個會被合併傳給context的字典: 接收一個request對象做爲參數,返回一個包含了將被合併到context中的項的字典。
每一個處理器將會按照順序應用。 也就是說若是你在第一個處理器裏面向context添加了一個變量,而第二個處理器添加了一樣名字的變量,那麼第二個將會覆蓋第一個。
Django提供了幾個簡單的context處理器,有些在默認狀況下被啓用的。
django.core.context_processors.auth
若是 TEMPLATE_CONTEXT_PROCESSORS 包含了這個處理器,那麼每一個 RequestContext 將包含這些變量:
user :一個 django.contrib.auth.models.User 實例,描述了當前登陸用戶(或者一個 AnonymousUser 實例,若是客戶端沒有登陸)。
messages :一個當前登陸用戶的消息列表(字符串)。 在後臺,對每個請求,這個變量都調用 request.user.get_and_delete_messages() 方法。 這個方法收集用戶的消息而後把它們從數據庫中刪除。
perms : django.core.context_processors.PermWrapper 的一個實例,包含了當前登陸用戶有哪些權限。
關於users、permissions和messages的更多內容請參考第14章。
django.core.context_processors.debug
這個處理器把調試信息發送到模板層。 若是TEMPLATE_CONTEXT_PROCESSORS包含這個處理器,每個RequestContext將包含這些變量:
debug :你設置的 DEBUG 的值( True 或 False )。你能夠在模板裏面用這個變量測試是否處在debug模式下。
sql_queries :包含相似於 ``{‘sql’: …, ‘time’: `` 的字典的一個列表, 記錄了這個請求期間的每一個SQL查詢以及查詢所耗費的時間。 這個列表是按照請求順序進行排列的。
System Message: WARNING/2 (<string>, line 315); backlink
Inline literal start-string without end-string.
因爲調試信息比較敏感,因此這個context處理器只有當同時知足下面兩個條件的時候纔有效:
DEBUG 參數設置爲 True 。
請求的ip應該包含在 INTERNAL_IPS 的設置裏面。
細心的讀者可能會注意到debug模板變量的值永遠不可能爲False,由於若是DEBUG是False,那麼debug模板變量一開始就不會被RequestContext所包含。
django.core.context_processors.i18n
若是這個處理器啓用,每一個 RequestContext 將包含下面的變量:
LANGUAGES : LANGUAGES 選項的值。
LANGUAGE_CODE :若是 request.LANGUAGE_CODE 存在,就等於它;不然,等同於 LANGUAGE_CODE 設置。
附錄E提供了有關這兩個設置的更多的信息。
django.core.context_processors.request
若是啓用這個處理器,每一個 RequestContext 將包含變量 request , 也就是當前的 HttpRequest 對象。 注意這個處理器默認是不啓用的,你須要激活它。
若是你發現你的模板須要訪問當前的HttpRequest你就須要使用它:
{{ request.REMOTE_ADDR }}

寫Context處理器的一些建議 編寫處理器的一些建議: 使每一個context處理器完成儘量小的功能。 使用多個處理器是很容易的,因此你能夠根據邏輯塊來分解功能以便未來複用。 要注意 TEMPLATE_CONTEXT_PROCESSORS 裏的context processor 將會在基於這個settings.py的每一個 模板中有效,因此變量的命名不要和模板的變量衝突。 變量名是大小寫敏感的,因此processor的變量全用大寫是個不錯的主意。 不論它們存放在哪一個物理路徑下,只要在你的Python搜索路徑中,你就能夠在 TEMPLATE_CONTEXT_PROCESSORS 設置裏指向它們。 建議你把它們放在應用或者工程目錄下名爲 context_processors.py 的文件裏。

相關文章
相關標籤/搜索