這篇文章主要介紹了在Django的通用視圖中處理Context的方法,Django是最具人氣的Python web開發(fā)框架,需要的朋友可以參考下
制作友好的模板Context
你也許已經(jīng)注意到范例中的出版商列表模板在變量 object_list 里保存所有的書籍。這個(gè)方法工作的很好,只是對(duì)編寫模板的人不太友好。 他們必須知道這里正在處理的是書籍。 更好的變量名應(yīng)該是publisher_list,這樣變量所代表的內(nèi)容就顯而易見了。
我們可以很容易地像下面這樣修改 template_object_name 參數(shù)的名稱:
- from django.conf.urls.defaults import *
- from django.views.generic import list_detail
- from mysite.books.models import Publisher
- publisher_info = {
- 'queryset': Publisher.objects.all(),
- 'template_name': 'publisher_list_page.html',
- 'template_object_name': 'publisher',
- }
- urlpatterns = patterns('',
- (r'^publishers/$', list_detail.object_list, publisher_info)
- )
在模板中,通用視圖會(huì)通過在template_object_name后追加一個(gè)_list的方式來創(chuàng)建一個(gè)表示列表項(xiàng)目的變量名。
使用有用的 template_object_name 總是個(gè)好想法。 你的設(shè)計(jì)模板的合作伙伴會(huì)感謝你的。
添加額外的Context
你常常需要呈現(xiàn)比通用視圖提供的更多的額外信息。 例如,考慮一下在每個(gè)出版商的詳細(xì)頁面顯示所有其他出版商列表。 object_detail 通用視圖為context提供了出版商信息,但是看起來沒有辦法在模板中 獲取 所有 出版商列表。
這是解決方法: 所有的通用視圖都有一個(gè)額外的可選參數(shù) extra_context 。這個(gè)參數(shù)是一個(gè)字典數(shù)據(jù)類型,包含要添加到模板的context中的額外的對(duì)象。 所以要給視圖提供所有出版商的列表,我們就用這樣的info字典:
- publisher_info = {
- 'queryset': Publisher.objects.all(),
- 'template_object_name': 'publisher',
- **'extra_context': {'book_list': Book.objects.all()}**
- }
這樣就把一個(gè) {{ book_list }} 變量放到模板的context中。 這個(gè)方法可以用來傳遞任意數(shù)據(jù) 到通用視圖模板中去,非常方便。 這是非常方便的
不過,這里有一個(gè)很隱蔽的BUG,不知道你發(fā)現(xiàn)了沒有?
我們現(xiàn)在來看一下, extra_context 里包含數(shù)據(jù)庫查詢的問題。 因?yàn)樵谶@個(gè)例子中,我們把 Publisher.objects.all() 放在URLconf中,它只會(huì)執(zhí)行一次(當(dāng)URLconf第一次加載的時(shí)候)。 當(dāng)你添加或刪除出版商,你會(huì)發(fā)現(xiàn)在重啟Web服務(wù)器之前,通用視圖不會(huì)反映出這些修改(有關(guān)QuerySet何時(shí)被緩存和賦值的更多信息請(qǐng)參考附錄C中“緩存與查詢集”一節(jié))。
備注
這個(gè)問題不適用于通用視圖的 queryset 參數(shù)。 因?yàn)镈jango知道有些特別的 QuerySet 永遠(yuǎn)不能 被緩存,通用視圖在渲染前都做了緩存清除工作。
解決這個(gè)問題的辦法是在 extra_context 中用一個(gè)回調(diào)(callback)來代替使用一個(gè)變量。 任何傳遞給extra_context的可調(diào)用對(duì)象(例如一個(gè)函數(shù))都會(huì)在每次視圖渲染前執(zhí)行(而不是只執(zhí)行一次)。 你可以象這樣定義一個(gè)函數(shù):
- **def get_books():**
- **return Book.objects.all()**
- publisher_info = {
- 'queryset': Publisher.objects.all(),
- 'template_object_name': 'publisher',
- 'extra_context': **{'book_list': get_books}**
- }
或者你可以使用另一個(gè)不是那么清晰但是很簡(jiǎn)短的方法,事實(shí)上 Publisher.objects.all 本身就是可以調(diào)用的:
- publisher_info = {
- 'queryset': Publisher.objects.all(),
- 'template_object_name': 'publisher',
- 'extra_context': **{'book_list': Book.objects.all}**
- }
注意 Book.objects.all 后面沒有括號(hào);這表示這是一個(gè)函數(shù)的引用,并沒有真正調(diào)用它(通用視圖將會(huì)在渲染時(shí)調(diào)用它)。
新聞熱點(diǎn)
疑難解答
圖片精選