我們前面講的幾次admin是Django的"殺手級特性",并且大多數(shù)Django開發(fā)人員很快愛上了它節(jié)省時(shí)間的所有特性
這樣自然而然的大部分Django開發(fā)人員開始尋找自定義或者擴(kuò)展admin的方法
第6章最后幾部分講到了一些定制admin界面某一部分的簡單方法,重新閱讀一下那些資料是個(gè)好主意
它講述了一些定制admin的更改列表,編輯表單以及l(fā)ogo等等的簡單方法
第6章也討論了何時(shí)和為什么你想使用admin界面,這些資料跳躍到了其他章節(jié),我們這里重新介紹一下:
顯然,admin對編輯數(shù)據(jù)非常有用(fancy that),如果你有一些錄入數(shù)據(jù)的任務(wù),則admin不可能被其它東西打敗
我們料想大多數(shù)本書的讀者都將有很多數(shù)據(jù)錄入的任務(wù)
Django的admin在非技術(shù)用戶需要錄入數(shù)據(jù)時(shí)特別閃耀,這是這個(gè)特性的最初起源
盡管如此,我們發(fā)現(xiàn)除了顯而易見的數(shù)據(jù)錄入任務(wù),admin也在下面一些情況下有用:
1,檢查數(shù)據(jù)模型,我們定義了一個(gè)新模型后第一件事就是在admin里調(diào)用它并輸入一些模擬數(shù)據(jù),這對我們發(fā)現(xiàn)數(shù)據(jù)
模型的錯(cuò)誤并有一個(gè)圖形界面來顯示這些錯(cuò)誤很有幫助
2,管理必須的數(shù)據(jù),對于chicagocrime.org來說很少有數(shù)據(jù)錄入的任務(wù),因?yàn)樗臄?shù)據(jù)都來自于一個(gè)自動(dòng)的數(shù)據(jù)源
盡管如此,當(dāng)自動(dòng)獲取數(shù)據(jù)的模塊出問題時(shí),通過admin可以輕松的編輯數(shù)據(jù),這是很有用的
Django的admin不需要或者需要很少配置就可以處理這些常見的情況,但是,處理這些常見的情況如此的好意味著
Django的admin在處理其它情形時(shí)不一定很好
我們后面將談到Django的admin不適合做的一些事情,但是現(xiàn)在我們先離題來看看它的一些哲學(xué):
admin的禪宗
作為它的核心,Django的admin設(shè)計(jì)用來為如下的一個(gè)單獨(dú)的活動(dòng):
受信任的用戶編輯結(jié)構(gòu)化的內(nèi)容
是的,很簡單,但是這簡單的一行隱藏著很多內(nèi)容,Django的admin的整個(gè)哲學(xué)都基于此
讓我們深入了解這個(gè)句子的子內(nèi)容:
"受信任的用戶"
admin設(shè)計(jì)來被你(開發(fā)者)信任的人用,這不僅僅表示那些被授權(quán)的用戶,它表示Django假設(shè)你的內(nèi)容編輯者可以
被信任來做正確的事情,這意味著編輯內(nèi)容沒有批準(zhǔn)的過程,如果你信任你的用戶,沒有人需要對編輯的批準(zhǔn)
這也表明了權(quán)限系統(tǒng)不支持基于一個(gè)對象的限制訪問
如果你信任某人來編輯他自己的故事,你也將信任他不會(huì)在沒有權(quán)限的情況下編輯別人的故事
"編輯"
Django的admin的首要目的是讓人們編輯內(nèi)容,這最初看起來很顯而易見,但是也存在一些細(xì)小而強(qiáng)大的影響
例如,盡管admin對重新視查數(shù)據(jù)很有用,但是它不是設(shè)計(jì)來干這個(gè)的,注意缺少"can view"權(quán)限(參考第12章)
Django假設(shè)如果用戶被允許在admin里查看內(nèi)容,他們也被允許編輯它
另外一個(gè)很值得注意的地方是admin缺少一些例如"工作流"的東西,如果一些任務(wù)需要幾步來完成,admin不支持
特別的順序來做這件事情,admin關(guān)注于編輯,而不是圍繞編輯的其它活動(dòng)
對于工作流的缺乏支持也起源于信任的原則,admin的哲學(xué)是,工作流屬于個(gè)人問題,而不應(yīng)該用代碼實(shí)現(xiàn)
最后,注意admin缺乏統(tǒng)計(jì)的支持,它不支持顯示總數(shù),平均數(shù)等等
再一次說明,admin是用來編輯的,它期望你寫自定義的視圖來完成其它的任務(wù)
"結(jié)構(gòu)化的內(nèi)容"
因?yàn)镈jango其它部分的關(guān)系,admin希望你與結(jié)構(gòu)化的數(shù)據(jù)工作,這樣,admin僅僅支持編輯用Django模型存儲(chǔ)的數(shù)據(jù)
對于其它形式的數(shù)據(jù),你則需要自定義視圖
總結(jié)
現(xiàn)在應(yīng)該很清楚了,Django的admin不是給任何用戶來做任何事情的,而是牢牢的關(guān)注一點(diǎn)并且把這一點(diǎn)做的非常好
當(dāng)我們需要擴(kuò)展Django的admin時(shí),同一哲學(xué)的大部分內(nèi)容存在與此(注意擴(kuò)展性無處不在)
因?yàn)樽远x的Django視圖可以做任何事情,而且它們可以可視化的集成到admin(參看下面內(nèi)容),內(nèi)建的定制admin的
機(jī)會(huì)在一定程序上被設(shè)計(jì)所限制
定制admin模板
我們下面將看到,你有幾種工具來定制內(nèi)建的admin模板,但是對于其它任務(wù),例如需要自定義工作流或者細(xì)粒度權(quán)限
你將需要閱讀本章末尾講到的定制admin視圖
現(xiàn)在我們來看看快速定制admin的外觀和行為,第6章講到了一些常見的任務(wù),如更改logo樣式和提供自定義admin表單
就這點(diǎn)來說,我們通常需要更改一個(gè)特殊項(xiàng)的一些模板
admin的每一個(gè)視圖,如更改列表,編輯表單,刪除確認(rèn)頁面,歷史視圖等都有一個(gè)分配的模板
而這個(gè)模板可以通過幾種方式來覆蓋
首先,你可以全局覆蓋模板,admin視圖使用標(biāo)準(zhǔn)模板載入機(jī)制來尋找模板,所以如果你在你的模板目錄里創(chuàng)建模板
Django將載入并使用這些模板而不是使用Django綁定的默認(rèn)admin模板
這些全局模板如下:
視圖 基本模板名
更改列表 admin/change_list.html
增加/編輯表單 admin/change_form.html
刪除確認(rèn) admin/delete_confirmation.html
對象歷史 admin/object_history.html
盡管如此,大多數(shù)情況下你只想更改一個(gè)單獨(dú)的對象或者app的模板而不是全局的模板
這樣的話,每個(gè)admin視圖首先尋找模型和app專有的模板,這些視圖按下面的順序?qū)ふ夷0?
admin/<app_lable>/<object_name>/<template>.html
admin/<app_lable>/<template>.html
admin/<template>.html
例如,在bookstore app的Book模型的增加/編輯表單的視圖(第6章的例子)按下面的順序?qū)ふ夷0?
admin/bookstore/book/change_form.html
admin/bookstore/change_form.html
admin/change_form.html
定制模型模板
大多數(shù)情況下,你想使用上面第一個(gè)模板來創(chuàng)建模型專有的模板
通常情況下通過擴(kuò)展基本模板并在其中的塊定義中添加信息會(huì)將這個(gè)任務(wù)完成的最好
例如我們想在book頁面頂端添加一些幫助內(nèi)容,可能像下面這樣:
[img][/img]
這很容易做到,創(chuàng)建一個(gè)叫admin/bookstore/book/change_form.html的模板并且插入下面的代碼:
- {% extends "admin/change_form.html" %}
- {% block form_top %}
- <p>Insert meaningful help message here..</p>
- {% endblock %}
所有的這些模板都定義了一些塊來讓你覆蓋,對于大多數(shù)程序,代碼就是最好的文檔,所以我們鼓勵(lì)你瀏覽admin模板
(在django/contrib/admin/templates/里面)來得到最新的信息
定制JavaScript
使用這個(gè)自定義的模型模板最常見的用途就是添加自定義的JavaScript到admin頁面,可能是實(shí)現(xiàn)一些特殊的小窗口部件
或者是客戶端行為
幸運(yùn)的是,這再簡單不過了,每個(gè)admin模板定義了一個(gè){% block extrahead %},你可以把使用它來把其它的內(nèi)容添加
到head元素里去,例如你想在你的一個(gè)admin歷史頁面引入jQuery:
- {% extends "admin/object_history.html" %}
- {% block extrahead %}
- <script src="http://media.example.com/javascript/jquery.js" type="text/javascript"></script>
- <script type="text/javascript">
- // code to actually use jQuery here...
- </script>
- {% endblock %}
我不知道為什么你在對象歷史頁面需要jQuery,但是這個(gè)例子適用于admin的任何模板
你可以使用這個(gè)技術(shù)來引入任何其它你可能需要的JavaScript小窗口部件
定制admin視圖
到目前為止那些想添加自定義行為到Django的admin中的人們可能開始困惑了,他們會(huì)喊,"你所講述的都是關(guān)于怎樣改變
admin的外觀,但是我怎樣改變admin的工作方式呢?"
好了,別喊了,這里就是答案
需要理解的第一件事就是它一點(diǎn)也不神奇,admin做的任何事都不特殊,它只是一些像其它視圖一樣處理數(shù)據(jù)的視圖罷了
這些視圖在django.contrib.admin.views,當(dāng)然這里有很多代碼,它必須處理所有的選項(xiàng),域類型和影響模型行為的設(shè)置
同樣的,當(dāng)你意識到admin只是一些視圖時(shí),添加自定義的admin視圖就變得更容易理解
讓我們添加一個(gè)"publisher report"視圖到我們第6章的book app中,我們將構(gòu)建一個(gè)admin視圖來顯示通過publisher
分組的books列表,這是一個(gè)非常典型你可能想構(gòu)建的自定義admin"report"的例子
首先我們在URLconf里面包裝一個(gè)視圖,我們需要把這行代碼插入到admin視圖的引入行之前
- (r'^admin/bookstore/report/$', 'bookstore.admin_views.report'),
完整的URL配置可能像下面這樣:
- from django.conf.urls.defaults import *
- urlpatterns = patterns('',
- (r'^admin/bookstore/report/$', 'bookstore.admin_views.report'),
- (r'^admin/', include('django.contrib.admin.urls')),
- )
為什么把自定義視圖放在admin引入之前?回想一下Django處理URL模式的順序,因?yàn)閍dmin的引入U(xiǎn)RL匹配幾乎所有的東西
如果我們把上面的兩行URL配置代碼調(diào)換順序,Django將會(huì)查找一個(gè)內(nèi)建的視圖來匹配這個(gè)URL,這將不能工作
在這種特殊情況下,Django將試圖載入bookstore app的Report模型的更改列表,這是不存在的
現(xiàn)在讓我們來寫我們的視圖,為了簡單起見,我們只是載入所有的books在context里并讓模板使用{% regroup %}標(biāo)簽處理
分組,用下面的代碼創(chuàng)建一個(gè)bookstore/admin_views.py文件:
- from bookstore.models import Book
- from django.template import RequestContext
- from django.shortcuts import render_to_response
- from django.contrib.admin.views.decorators import staff_member_required
- @staff_member_required
- def report(request):
- return render_to_response(
- "admin/bookstore/report.html",
- {'book_list' : Book.objects.all()},
- RequestContext(request, {}),
- )
因?yàn)槲覀儼逊纸M留給模板來做,這個(gè)視圖非常簡單,盡管如此,這里有一些細(xì)小的東西值得解釋:
1,我們使用django.contrib.admin.views.decorators的staff_member_required裝飾器,它類似于第12章討論的
login_required裝飾器,但是這個(gè)還檢查給定的用戶是否標(biāo)記為"staff"成員來決定是否允許訪問admin
這個(gè)裝飾器保護(hù)所有內(nèi)建的admin視圖,讓你的視圖的認(rèn)證邏輯和admin的其它部分匹配
2,我們渲染在admin/下面的模板,雖然這沒有嚴(yán)格的要求,但是保持你所有的admin模板分組在一個(gè)admin目錄下
被認(rèn)為是最佳實(shí)踐,我們把模板放在我們的app后面叫bookstore的目錄下也是最佳實(shí)踐
3,我們使用RequestContext作為第3個(gè)參數(shù)(context_instance)傳遞給render_to_response
這保證了關(guān)于當(dāng)前用戶的信息可以在模板里得到,參看第10章得到更多關(guān)于RequestContext的信息
最后我們將為這個(gè)視圖創(chuàng)建一個(gè)模板,我們繼承內(nèi)建的admin模板來使這個(gè)視圖視覺上看起來是admin的一部分:
- {% extends "admin/base_site.html" %}
- {% block title %}List of books by publisher{% endblock %}
- {% block content %}
- <div id="content-main">
- <h1>List of books by publisher:</h1>
- {% regroup book_list|dictsort:"publisher.name" by publisher as books_by_publisher %}
- {% for publisher in books_by_publisher %}
- <h3>{{ publisher.grouper }}</h3>
- <ul>
- {% for book in publisher.list|dictsort:"title" %}
- <li>{{ book }}</li>
- {% endfor %}
- </ul>
- {% endfor %}
- </div>
- {% endblock %}
通過繼承admin/base_site.html我們"免費(fèi)"得到Django的admin的外觀,它看起來像這樣:
[img][/img]
今天你需要在哪里使用admin?
你可以使用這個(gè)技術(shù)來向admin添加任何你想到的東西,記住所謂的"定制admin視圖"事實(shí)上只是普通的Django視圖
你可以使用你在本書其它部分所學(xué)的所有技術(shù)來構(gòu)建任意復(fù)雜的admin視圖
我們將以一些自定義admin視圖的一些好注意結(jié)束本章內(nèi)容
覆蓋內(nèi)建的視圖
默認(rèn)的admin視圖不包含這些,你可以很輕松的在admin的任何地方跳轉(zhuǎn)到你的自定義視圖,只需讓你的URL覆蓋掉內(nèi)建的那些
例如,我們可以用一個(gè)簡單的讓用戶輸入ISBN的表單替代內(nèi)建的book創(chuàng)建視圖,然后我們就可以從http://isbn.nu/來查詢
book信息和自動(dòng)創(chuàng)建對象
這個(gè)視圖的代碼留給讀者做練習(xí),最重要的部分是下面的URL配置:
- (r'^admin/bookstore/book/add/$', 'bookstore.admin_views.add_by_isbn'),
如果這段代碼在你的URL配置中放在admin的URL前面的話,add_by_isbn視圖將完全替代標(biāo)準(zhǔn)的admin視圖
我們可以遵循類似的動(dòng)作來替代刪除確認(rèn)頁面,編輯頁面或者admin的任何其它部分
安徽新華電腦學(xué)校專業(yè)職業(yè)規(guī)劃師為你提供更多幫助【在線咨詢】