正如我們之前多次提到的,Django的管理介面是該框架的殺手級特性之一,多數 Django開發人員都知道它既省時又好用。由於此管理介面極受歡迎,對
Django開發人員來說,想對它進行客製化和拓展是件很平常的事。
Django管理網站的最後幾節介紹了客製化部分管理介面的一些簡單方法。在進入本章之前,請先複習一下那部分資料;其中涵蓋瞭如何自訂管理介面的 change list和
edit forms ,以及如何將管理介面冠以與網站一致的風格。
Django管理站點也討論了何時以及如何使用管理介面,由於那些資料對本章剩下內容是個好的起點,在此我們將重溫一遍:
顯而易見,對數據編輯顯而易見,對數據編輯顯而易見工作來說,這個管理介面極為有用(想像一下)。如果用於完成某種資料的輸入工作,則該管理介面實在是無人能及。我們猜想本書絕大多數讀者都有成堆資料輸入任務。
Django管理介面特別關注那些沒有技術背景的使用者來使用資料輸入;這也是該功能的開發目的。在Django最初開發地報社,開發一個典型的線上市政供水品質報告系統,需求如下:
§ 負責該題材的記者與某個開發人員會面,提交現有數據。
§ 開發人員圍繞該數據設計一個模型,並為該記者開發出管理介面。
§ 在記者將資料輸入 Django的同時,程式設計師就可以專注於開發公眾存取介面了(最有趣的部分!)。
換句話說,Django管理介面之所以存在的首要目的是為了方便內容編輯人員和程式設計師同時開展工作。
當然,除了顯而易見的資料輸入任務之外,我們發現管理介面在其他一些情況下有是很有用處的。
§ 查驗資料模型:定義好一個新的資料模型以後,我們要做的第一件事情就是在管理介面中將它運作起來,然後輸入一些假想資料。通常在發現資料建模出錯後,用圖形化的模型介面可以快速找到癥結所在。
§ 管理獲得的資料:很少有真實資料輸入會和像http://chicagocrime.org這樣的網站相關聯,因為多數資料來自自動產生的來源。然而,當所取得的資料出錯而導致麻煩時,能夠方便地找到並修改出錯資料將會有助於問題解決。
無需或僅需略為客製化之後, Django管理介面就能處理絕大部分常見情況。然而,正是因為在設計上極力折衷, Django管理介面能夠很好地處理這種常見情況也意味著它無法同樣處理其它一些編輯模型。
稍後,我們將討論哪些不是Django管理介面設計用來處置的情形,但首先讓我們暫時岔開話題,討論一下它的設計理念。
管理之道
在核心部分,Django管理介面只被設計用於一種行為:
受信任用戶編輯結構化的內容。
是的,這非常的簡單,但這種簡單是建立在一整堆假定之上的。 Django管理介面的全部設計理念都直接遵循這些假定,因此讓我們深入理解這些後續小節中所出現術語的含義。
受信任使用者
管理介面被設計成由你這樣的開發人員所信任的人使用。這裡所指的並非只是經過驗證的人;而是說 Django假定可以相信內容編輯者只會做對的事情。
反過來說,這也意味著如果你信任用戶,他們無需徵得許可就能編輯內容,也沒有人需要對他們的編輯行為進行許可。另一層意義是,儘管認證系統功能強大,但到本書寫作時為止,它並不支援物件層級基礎的存取限制。如果你允許某人對自己的新聞報導進行編輯,你必須能夠確信該用戶不會未經許可對其他人的報道進行編輯。
編輯
Django 管理介面的首要目的是讓使用者編輯資料。乍看之下這是顯而易見的,但仔細一想卻又變得有點難以捉摸和不同凡響。
舉例來說,雖然管理介面非常便於查驗資料(如剛才所討論的那樣),但這並不是它的設計初衷。例如我們在Django會話、使用者和註冊中談到的,它缺少視圖許可。 Django假定如果某人在管理介面中可以查看內容,那麼也可以進行編輯。
還有件更重要的事情要注意,那就是對於遠端呼叫工作流程的缺乏。如果某個特定任務由一系列步驟組成,沒有任何機制可以確保這些步驟能夠以某個特定順序完成。 Django管理介面專注於編輯,而不關心修改週邊的活動。對工作流程的這種迴避也源自於信任原則:管理介面的設計理念是工作流程乃人為事物,無需在程式碼中實現。
最後,要注意的是管理介面中缺少聚合。也就是說,不支援顯示總計、平均值之類的東西。再次重申,管理介面只用於編輯——它預期你將透過定義視圖來完成其它所有工作。
結構化的內容
在 Django其它部分配合下,管理介面希望你使用結構化的資料。因此,它只支援儲存於 Django模型中的數據進行編輯;對其它的數據,例如檔案系統中的數據,你必須自訂視圖來編輯。
就此打住
現在可以肯定的是,Django的管理介面並不打算成為所有人的萬能工具;相反我們選擇了專心做一件事情,並把它完成得盡善盡美。
進行 Django的管理介面拓展時,必須堅持同樣的設計理念。 (注意,可擴展性並不是我們的目標)。由於透過客製化 Django視圖可以做任何事,同時也因為它們可以輕鬆地透過視覺化方式整合到管理介面中(將在下一章將要描述),客製化管理介面的內建機會特意地受到一點限制。
必須記住,儘管管理介面很複雜,但它始終只是一個應用程式。只要有充足的時間,任何Django的開發者都能做到admin介面做到的所有事。因此,我們需要寄望於將來會有一個完全不同的admin介面會出現,這個新的介面擁有一系列不同的前提假設,而且工作方式也完全不同。
最後要指出的是,在本文寫作之時,Django開發者們正在進行一個新的管理介面的開發工作,該版本將提供更多客製化靈活性。當你閱讀本文時,這些新功能也許已經進入了真實的 Django發布之中。你可以向
Django社群的某些人了解是否已經整合了 newforms-admin主幹程式碼。
客製化管理範本
Django提供了一些用於自訂內建admin管理範本的工具,我們將簡略地介紹一下。而對於其他的任務(例如工作流程的控制,或更細緻的權限管理),你需要閱讀這一章中的建立自訂的admin視圖一節。
現在,讓我們來看看如何來快速自訂admin管理介面的外觀。 Django管理網站講到了一些最常見的任務:修改商標(為那些討厭藍色的尖發老闆),或提供一個自訂的form。
更進一步的目標常常會包含,改變模板中的一些特殊的項。每一種admin的視圖,包括修改清單、編輯表單、刪除確認頁以及歷史視圖,都有一個與之相關聯的範本可以以多種方式來進行覆蓋。
首先,你可以在全域上覆蓋模板。 admin視圖使用標準的範本載入機制來尋找範本。所以如果你在模板目錄中建立了一個新的模板,Django會自動地載入它。全域的模板在表17-1中列出。
表17-1. 全局管理模板
視圖 基模板名字
Change list admin/change_list.html
Add/edit form admin/change_form.html
Delete confirmation admin/delete_confirmation.html
Object history admin/object_history.html
§ admin/<app_label>/<object_name>/<template>.html § admin/<app_label>/<template>.html § admin/<template>.html
§ admin/books/book/change_form.html § admin/books/change_form.html § admin/change_form.html
自訂模型範本
自訂模型範本
这做起来非常容易:只要建立一个admin/bookstore/book/change_form.html模板,并输入下面的代码:
{% extends "admin/change_form.html" %} {% block form_top %} <p>Insert meaningful help message here...</p> {% endblock %}
所有这些模板都定义了一些可以被覆盖的块。对于大多数的应用程序来说,代码就是最好的文档,所以我们鼓励你能够详细阅读admin的模板来获得最新的信息(它们在django/contrib/admin/templates/)。
自定义JavaScript
这些自定义模型模板的常见用途包括,给admin页面增加自定义的javascript代码来实现一些特殊的视图物件或者是客户端行为。
幸运的是,这可以更简单。每一个admin模板都定义了{% block extrahead %},你可以在
元素中加入新的内容。例如你想要增加jQuery(http://jquery.com/)到你的admin历史中,可以这样做:{% 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放入到历史页中,但是这个例子可以被用到任何的模板中。
你可以使用这种技巧,加入任何的javascript代码。
创建自定义管理视图
现在,想要往Django的admin管理接口添加自定义行为的人,可能开始觉得有点奇怪了。我们这里所讲的都是如何改变admin管理接口的外观。他们都在喊:如何才能改变admin管理接口的内部工作机制。
首先要提的一点是,这并不神奇。admin管理接口并没有做任何特殊的事情,它只不过是和其他一些视图一样,简单地处理数据而已。
确实,这里有相当多的代码;它必须处理各种各样的操作,字段类型和设置来展示模型的行为.当你注意到ADMIN界面只是一系列视图(Views)的集合,增加自定义的管理视图就变得容易理解了。
作为举例,让我们为Django管理站点中的图书申请增加一个出版商报告的视图。建立一个admin视图用于显示被出版商分好类的书的列表,一个你要建立的自定义admin报告试图的极典型的例子。
首先,在我们的URLconf中连接一个视图。插入下面这行:
(r'^admin/books/report/$', 'mysite.books.admin_views.report'), 在将这行加入这个admin视图之前,原本的URLconf应该是这样: from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^admin/bookstore/report/$', 'bookstore.admin_views.report'), (r'^admin/', include('django.contrib.admin.urls')), )
为什么要将定制试图置于管理内容之前呢?回想一下,Django是按照顺序处理 URL
匹配式的。管理内容几乎匹配内容点之后所有的东西,因此如果我们把这几行的顺序颠倒一下, Django将会为该匹配式找到一个车内建管理视图,并将试图在books应用程序中为Report模型再入更新列表,而这却是不存在的。
现在我们开始写视图。为了简单起见,我们只把所有书籍加载到上下文中,让模板用{% regroup %}标签来处理分组操作。创建books/admin_views.py文件并写入以下内容:
from mysite.books.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 def report(request): return render_to_response( "admin/books/report.html", {'book_list' : Book.objects.all()}, RequestContext(request, {}), ) report = staff_member_required(report)
因为我们但分组操作留给了模板,该视图非常简单。然而,有几段微妙的细节值得我们搞清楚。
我们使用了django.contrib.admin.views.decorators中的staff_member_required修饰器。该修饰器与Django会话、用户和注册中讨论的login_required类似,但它还检查所指定的用户是否标记为内部人员,以决定是否允许他访问管理界面。
该修饰器保护所有内容的管理视图,并使得视图的身份验证逻辑匹配管理界面的其它部分。
我们在admin/之下解析了一个模板。尽管并非严格要求如此操作,将所有管理模板分组放在admin目录中是个好的做法。我们也将应用程序所有的模板放置在名叫books的目录中,这也是最佳实践。
我们将RequestContext用作render_to_response的第三个参数(``context_instance``)。这就确保了模板可访问当前用户的信息。
参看Django输出非HTML内容了解更多关于RequestContext的信息。
最后,
我们为这个视图做一个模板。我们将扩展内置管理模板,以使该视图明确地成为管理界面的一部分.
{% 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管理界面的外观。图
17-2 我展示了像这样的一个最终结果。
图 17-2.一个自定义按出版商归类的图书管理视图
使用该技术,你可以向管理界面中添加任何你梦想中的东西。需要记住的是这些被叫做定制管理视图实际不过是普通的 Django视图,你可以使用在本书其它部分所学到的技术制作出符合自己需要的复杂管理界面。
下面用自定义admin视图的一些概念总结一下本章。
覆盖内置视图
有时缺省的管理视图无法完成某项工作。你可以轻松地换上自己的定制视图;只需要用自己的 URL遮蔽内建的管理视图。也就是说,如果在 URLConf中你的视图出现在缺省管理视图之前,你的视图将取代缺省视图被调用。
举例来说,我们可以用一个让用户简单输入 ISBN的窗体来取代内建的书籍创建视图。然后,我们可以从http://isbn.nu/查询该书的信息,并自动地创建对象。
这样的视图的代码留给读者作为一个练习,重要的部分是这个 URLconf代码片断:
(r'^admin/bookstore/book/add/$', 'mysite.books.admin_views.add_by_isbn'),
如果这个代码片段在 URLConf中出现于管理 URL
之前,add_by_isbn视图将完全取代标准的管理视图。
按照这种方式,我们可以替换删除确认页、编辑页面或者管理界面的其它任何部分
以上就是Django 管理界面的内容,更多相关内容请关注PHP中文网(www.php.cn)!