原文地址:http://jjz.javaeye.com/blog/282805
默認(rèn)情況下,模板是不能訪問(wèn)request的。要在模板里使用request,其實(shí)很簡(jiǎn)單。
首先,在視圖里,我們不能再使用默認(rèn)的Context(django.template.Context),而是要使用它的子類(lèi)RequestContext (django.template.RequestContext),這個(gè)類(lèi)很好很強(qiáng)大,一會(huì)你就知道了!
RequestContext的第一個(gè)參數(shù)是HttpRequest對(duì)象,在視圖中我們直接使用request就行。
把以前的Python代碼
c = Context(request, dict)
改成Python代碼
c = RequestContext(request, dict)
dict是你想傳遞給模板的字典。
如果以前使用的是人見(jiàn)人愛(ài)的render_to_response
Python代碼
return render_to_response('template.html', {...})
改成
Python代碼
return render_to_response('template.html', {...}, context_instance=RequestContext(request))
也就是增加一個(gè)context_instance參數(shù)。
光這樣還不行。在配置文件(一般是setting.py)中,找到TEMPLATE_CONTEXT_PROCESSORS,當(dāng)然,你也可能找不到,因?yàn)槟J(rèn)生成的setting.py中沒(méi)出現(xiàn)這個(gè)變量。無(wú)論如何,確保它的值是
Python代碼
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.request"
)
差不多了,到驗(yàn)證的時(shí)候了。在模板中加入一句{{ request }},是不是看到什么輸出了。使用{{ requset.session}}就可以訪問(wèn)session了。
為什么說(shuō)RequestContext很強(qiáng)大呢,下面接著說(shuō)TEMPLATE_CONTEXT_PROCESSORS是一個(gè)元組,里面的每一個(gè)字符串其實(shí)代表了一個(gè)可調(diào)用(callable)對(duì)象,比如一個(gè)函數(shù)或可調(diào)用類(lèi)。除了可調(diào)用外,它們滿足下面兩個(gè)條件:
1.只有一個(gè)request對(duì)象作為參數(shù)
2.而且要返回一個(gè)字典
你可以自定義context_processor,只要它滿足上面的條件就行。
RequestContext會(huì)把context_processor返回的字典并入自己,也就相當(dāng)于在context中添加了新的內(nèi)容,而這這些內(nèi)容可以直接在模板中訪問(wèn)。
默認(rèn)情況下TEMPLATE_CONTEXT_PROCESSORS的值是
Python代碼
(
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media"
)
所有的processor順序執(zhí)行,如果兩個(gè)不同的processor返回的字典中有相同的key,后面的會(huì)覆蓋前面的。
除了在TEMPLATE_CONTEXT_PROCESSORS中添加processor外,你還可以提供RequestContext額外的參數(shù)作為processor,例如
Python代碼
c = RequestContext(request, {...}, my_processor_1, my_processor_2...)
這種方式更靈活,不過(guò)也更麻煩。
好了,下面看看默認(rèn)的processor都干了些什么
1.django.core.context_processors.auth
它給context添加了三個(gè)變量(其實(shí)也就是說(shuō)它返回的字典中有三個(gè)key)
user :如果用戶登錄了,這就是一個(gè)auth.User的實(shí)例,代表當(dāng)前用戶。如果用戶沒(méi)有登錄,這就是AnonymousUser的實(shí)例,代表當(dāng)前的匿名用戶。
messages: 傳給當(dāng)前用戶的信息列表。
perms: django.core.context_processors.PermWrapper的實(shí)例,表示當(dāng)前用戶的授權(quán)。
2.django.core.context_processors.debug
這個(gè)家伙很懶,就算你把它放到了TEMPLATE_CONTEXT_PROCESSORS里,它也不愿意干活,你還要做點(diǎn)額外的工作才行。首先要確保在配置文件中DEBUG變量的值為T(mén)rue,然后,設(shè)置 INTERNAL_IPS,保證你的ip( 在request.META['REMOTE_ADDR']里可以看到 )在里面。
Python代碼
INTERNAL_IPS = ('127,0.0.1', ) #這是一個(gè)元組,每個(gè)ip都是字符串表示,本機(jī)設(shè)成127.0.0.1 都是字符串表示,做完這些,這家伙才開(kāi)始工作。它給context添加了兩個(gè)變量
debug :True,這樣我們可以在模板中使用{% if debug %}調(diào)試{% endif %}進(jìn)行模板調(diào)試
sql_queries: 表示本次請(qǐng)求所執(zhí)行的sql的字典列表,列表中的每個(gè)字典表示一次sql查詢,字典的格式是:{'sql':..., 'time':...},sql表示執(zhí)行的sql語(yǔ)句,time表示執(zhí)行這條語(yǔ)句所用的時(shí)間。這個(gè)功能實(shí)在太棒了,能查看生成的sql語(yǔ)句,心里踏實(shí)啊!
3.django.core.context_processors.i18n這個(gè)processor比較簡(jiǎn)單,它也是添加兩個(gè)變量(或者說(shuō)key?)
LANGUAGES :配置文件中的 LANGUAGES
LANGUAGE_CODE :如果reqeust中有 LANGUAGE_CODE,這個(gè)值等于request. LANGUAGE_CODE,否則這個(gè)值是配置文件中的 LANGUAGE_CODE。
如果不使用這個(gè),想在頁(yè)面獲取這兩個(gè)值可以使用:
{% get_current_language as LANGUAGE_CODE %}
{{LANGUAGE_CODE}}
{% get_available_languages as LANGUAGES %}|
{{LANGUAGES}}
4.django.core.context_processors.media
media processor是在Django1.0中才出現(xiàn)的,它使context包含MEDIA_URL,context[' MEDIA_URL '] = 配置文件中的MEDIA_URL。
5.django.core.context_processors.request
添加一個(gè)變量request,表示當(dāng)前請(qǐng)求的HttpRequest對(duì)象。
最重要的是可以自定義processor,如果很多模板頁(yè)面都需要某個(gè)數(shù)據(jù),自帶的processor又無(wú)法滿足,那就自己寫(xiě)一個(gè)出來(lái),不就是一個(gè)函數(shù)嘛,簡(jiǎn)單!