咱們根據數據庫創建了多個model,此時這個model也是用的admin的原生的模板,由於每一個model的樣式可能會不同,此時咱們能夠這樣作。
假如咱們要修更名字爲back的app的,且model名siteinfo的的change頁面,則咱們能夠按照以下步驟javascript
(1)在項目的templates創建admin/back/siteinfohtml
(2)在此目錄下創建change_form.html便可java
項目目錄:jquery
- shuili
- |-- back
- | |-- admin.py
- | |-- admin.pyc
- | |-- apps.py
- | |-- backcontroller.py
- | |-- backcontroller.pyc
- | |-- __init__.py
- | |-- __init__.pyc
- | |-- migrations
- | | |-- 0001_initial.py
- | | |-- 0001_initial.pyc
- | | |-- __init__.py
- | | `-- __init__.pyc
- | |-- models.py
- | |-- models.pyc
- | |-- tests.py
- | `-- views.py
- |-- manage.py
- |-- run.py
- |-- shuili
- | |-- __init__.py
- | |-- __init__.pyc
- | |-- settings.py
- | |-- settings.pyc
- | |-- urls.py
- | |-- urls.pyc
- | |-- wsgi.py
- | `-- wsgi.pyc
- `-- templates
- |-- admin
- | |-- back
- | | `-- siteinfo
- | | `-- change_form.html
- | `-- change_form.html
- `-- index.html
詳細:
admin的禪宗
做爲它的核心,Django的admin設計用來爲以下的一個單獨的活動:
受信任的用戶編輯結構化的內容
是的,很簡單,可是這簡單的一行隱藏着不少內容,Django的admin的整個哲學都基於此
讓咱們深刻了解這個句子的子內容:
"受信任的用戶"
admin設計來被你(開發者)信任的人用,這不只僅表示那些被受權的用戶,它表示Django假設你的內容編輯者能夠
被信任來作正確的事情,這意味着編輯內容沒有批准的過程,若是你信任你的用戶,沒有人須要對編輯的批准
這也代表了權限系統不支持基於一個對象的限制訪問
若是你信任某人來編輯他本身的故事,你也將信任他不會在沒有權限的狀況下編輯別人的故事
"編輯"
Django的admin的首要目的是讓人們編輯內容,這最初看起來很顯而易見,可是也存在一些細小而強大的影響
例如,儘管admin對從新視查數據頗有用,可是它不是設計來幹這個的,注意缺乏"can view"權限(參考第12章)
Django假設若是用戶被容許在admin裏查看內容,他們也被容許編輯它
另一個很值得注意的地方是admin缺乏一些例如"工做流"的東西,若是一些任務須要幾步來完成,admin不支持
特別的順序來作這件事情,admin關注於編輯,而不是圍繞編輯的其它活動
對於工做流的缺少支持也起源於信任的原則,admin的哲學是,工做流屬於我的問題,而不該該用代碼實現
最後,注意admin缺少統計的支持,它不支持顯示總數,平均數等等
再一次說明,admin是用來編輯的,它指望你寫自定義的視圖來完成其它的任務
"結構化的內容"
由於Django其它部分的關係,admin但願你與結構化的數據工做,這樣,admin僅僅支持編輯用Django模型存儲的數據
對於其它形式的數據,你則須要自定義視圖
總結
如今應該很清楚了,Django的admin不是給任何用戶來作任何事情的,而是緊緊的關注一點而且把這一點作的很是好
當咱們須要擴展Django的admin時,同一哲學的大部份內容存在與此(注意擴展性無處不在)
由於自定義的Django視圖能夠作任何事情,並且它們能夠可視化的集成到admin(參看下面內容),內建的定製admin的
機會在必定程序上被設計所限制
定製admin模板
咱們下面將看到,你有幾種工具來定製內建的admin模板,可是對於其它任務,例如須要自定義工做流或者細粒度權限
你將須要閱讀本章末尾講到的定製admin視圖
如今咱們來看看快速定製admin的外觀和行爲,第6章講到了一些常見的任務,如更改logo樣式和提供自定義admin表單
就這點來講,咱們一般須要更改一個特殊項的一些模板
admin的每個視圖,如更改列表,編輯表單,刪除確認頁面,歷史視圖等都有一個分配的模板
而這個模板能夠經過幾種方式來覆蓋
首先,你能夠全局覆蓋模板,admin視圖使用標準模板載入機制來尋找模板,因此若是你在你的模板目錄裏建立模板
Django將載入並使用這些模板而不是使用Django綁定的默認admin模板
這些全局模板以下:
視圖 基本模板名
更改列表 admin/change_list.html
增長/編輯表單 admin/change_form.html
刪除確認 admin/delete_confirmation.html
對象歷史 admin/object_history.html
儘管如此,大多數狀況下你只想更改一個單獨的對象或者app的模板而不是全局的模板
這樣的話,每一個admin視圖首先尋找模型和app專有的模板,這些視圖按下面的順序尋找模板:
admin/<app_lable>/<object_name>/<template>.html
admin/<app_lable>/<template>.html
admin/<template>.html
例如,在bookstore app的Book模型的增長/編輯表單的視圖(第6章的例子)按下面的順序尋找模板:
admin/bookstore/book/change_form.html
admin/bookstore/change_form.html
admin/change_form.html
定製模型模板
大多數狀況下,你想使用上面第一個模板來建立模型專有的模板
一般狀況下經過擴展基本模板並在其中的塊定義中添加信息會將這個任務完成的最好
例如咱們想在book頁面頂端添加一些幫助內容,可能像下面這樣:
[img][/img]
這很容易作到,建立一個叫admin/bookstore/book/change_form.html的模板而且插入下面的代碼:
數據庫
- {% extends "admin/change_form.html" %}
-
- {% block form_top %}
- <p>Insert meaningful help message here..</p>
- {% endblock %}
- {% extends "admin/change_form.html" %}
-
- {% block form_top %}
- <p>Insert meaningful help message here..</p>
- {% endblock %}
全部的這些模板都定義了一些塊來讓你覆蓋,對於大多數程序,代碼就是最好的文檔,因此咱們鼓勵你瀏覽admin模板
(在django/contrib/admin/templates/裏面)來獲得最新的信息
定製JavaScript
使用這個自定義的模型模板最多見的用途就是添加自定義的JavaScript到admin頁面,多是實現一些特殊的小窗口部件
或者是客戶端行爲
幸運的是,這再簡單不過了,每一個admin模板定義了一個{% block extrahead %},你能夠把使用它來把其它的內容添加
到head元素裏去,例如你想在你的一個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">
-
-
-
- </script>
- {% endblock %}
- {% extends "admin/object_history.html" %}
-
- {% block extrahead %}
- <script src="http://media.example.com/javascript/jquery.js" type="text/javascript"></script>
- <script type="text/javascript">
-
-
-
- </script>
- {% endblock %}
我不知道爲何你在對象歷史頁面須要jQuery,可是這個例子適用於admin的任何模板
你可使用這個技術來引入任何其它你可能須要的JavaScript小窗口部件
定製admin視圖
到目前爲止那些想添加自定義行爲到Django的admin中的人們可能開始困惑了,他們會喊,"你所講述的都是關於怎樣改變
admin的外觀,可是我怎樣改變admin的工做方式呢?"
好了,別喊了,這裏就是答案
須要理解的第一件事就是它一點也不神奇,admin作的任何事都不特殊,它只是一些像其它視圖同樣處理數據的視圖罷了
這些視圖在django.contrib.admin.views,固然這裏有不少代碼,它必須處理全部的選項,域類型和影響模型行爲的設置
一樣的,當你意識到admin只是一些視圖時,添加自定義的admin視圖就變得更容易理解
讓咱們添加一個"publisher report"視圖到咱們第6章的book app中,咱們將構建一個admin視圖來顯示經過publisher
分組的books列表,這是一個很是典型你可能想構建的自定義admin"report"的例子
首先咱們在URLconf裏面包裝一個視圖,咱們須要把這行代碼插入到admin視圖的引入行以前
- (r'^admin/bookstore/report/$', 'bookstore.admin_views.report'),
- (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')),
- )
- 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模式的順序,由於admin的引入URL匹配幾乎全部的東西
若是咱們把上面的兩行URL配置代碼調換順序,Django將會查找一個內建的視圖來匹配這個URL,這將不能工做
在這種特殊狀況下,Django將試圖載入bookstore app的Report模型的更改列表,這是不存在的
如今讓咱們來寫咱們的視圖,爲了簡單起見,咱們只是載入全部的books在context裏並讓模板使用{% regroup %}標籤處理
分組,用下面的代碼建立一個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, {}),
- )
- 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, {}),
- )
由於咱們把分組留給模板來作,這個視圖很是簡單,儘管如此,這裏有一些細小的東西值得解釋:
1,咱們使用django.contrib.admin.views.decorators的staff_member_required裝飾器,它相似於第12章討論的
login_required裝飾器,可是這個還檢查給定的用戶是否標記爲"staff"成員來決定是否容許訪問admin
這個裝飾器保護全部內建的admin視圖,讓你的視圖的認證邏輯和admin的其它部分匹配
2,咱們渲染在admin/下面的模板,雖然這沒有嚴格的要求,可是保持你全部的admin模板分組在一個admin目錄下
被認爲是最佳實踐,咱們把模板放在咱們的app後面叫bookstore的目錄下也是最佳實踐
3,咱們使用RequestContext做爲第3個參數(context_instance)傳遞給render_to_response
這保證了關於當前用戶的信息能夠在模板裏獲得,參看第10章獲得更多關於RequestContext的信息
最後咱們將爲這個視圖建立一個模板,咱們繼承內建的admin模板來使這個視圖視覺上看起來是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 %}
- {% 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咱們"免費"獲得Django的admin的外觀,它看起來像這樣:
[img][/img]
今天你須要在哪裏使用admin?
你可使用這個技術來向admin添加任何你想到的東西,記住所謂的"定製admin視圖"事實上只是普通的Django視圖
你可使用你在本書其它部分所學的全部技術來構建任意複雜的admin視圖
咱們將以一些自定義admin視圖的一些好注意結束本章內容
覆蓋內建的視圖
默認的admin視圖不包含這些,你能夠很輕鬆的在admin的任何地方跳轉到你的自定義視圖,只需讓你的URL覆蓋掉內建的那些
例如,咱們能夠用一個簡單的讓用戶輸入ISBN的表單替代內建的book建立視圖,而後咱們就能夠從http://isbn.nu/來查詢
book信息和自動建立對象
這個視圖的代碼留給讀者作練習,最重要的部分是下面的URL配置:
- (r'^admin/bookstore/book/add/$', 'bookstore.admin_views.add_by_isbn'),
- (r'^admin/bookstore/book/add/$', 'bookstore.admin_views.add_by_isbn'),
若是這段代碼在你的URL配置中放在admin的URL前面的話,add_by_isbn視圖將徹底替代標準的admin視圖
咱們能夠遵循相似的動做來替代刪除確認頁面,編輯頁面或者admin的任何其它部分