所謂網頁開發是有趣的,管理界面是千篇一律的。所以就有了django自動管理界面來減少重復勞動。
一、激活管理界面
1、django.contrib包
django自帶了很多優秀的附加組件,它們都存在於django.contrib包里,與django捆綁,使開發人員不需要重復造輪子。django.contrib是一套龐大的功能集,它是Django基本代碼的組成部分,Django框架就是由眾多包含附加組件(add-on)的基本代碼構成的。
django自動管理工具就是django.contrib的一部分。django自動管理工具被稱為django.contrib.admin。django.contrib中還有其他可以的特性,如用戶鑒別系統(django.contrib.auth)、支持匿名會話(django.contrib.sessions)以及用戶評注系統(django.contrib.comments)。
2、激活管理界面
因為管理界面是可選的,所以用之前首先要激活。
第一步,配置settings.py
1、在INSTALLED_APPS中取消注釋django.contrib.admin。(INSTALLED_APPS中的配置順序無關)
2、在INSTALLED_APPS取消注釋'django.contrib.auth','django.contrib.contenttypes'和'django.contrib.sessions',Django的管理工具需要這3個包。
3、在MIDDLEWARE_CLASSES中取消注釋'django.middleware.common.CommonMiddleware'、'django.contrib.sessions.middleware.SessionMiddleware'和'django.contrib.auth.middleware.AuthenticationMiddleware' 。
第二步,生成數據庫
運行python manage.py syncdb。生成管理界面使用的額外數據庫表。
把'django.contrib.auth'加入INSTALLED_APPS后,第一次運行syncdb命令時,系統會請你創建一個超級用戶。
liuxiaoyan@development:~/mysite$ python manage.py syncdb Creating tables ... Creating table auth_permission Creating table auth_group_permissions Creating table auth_group Creating table auth_user_user_permissions Creating table auth_user_groups Creating table auth_user Creating table auth_message Creating table django_content_type Creating table django_session Creating table django_admin_log You just installed Django's auth system, which means you don't have any superusers defined. Would you like to create one now? (yes/no):
第三步,配置URL
在urls.py中取消注釋admin相關的三行注釋
# Include these import statements... from django.contrib import admin admin.autodiscover() # And include this URLpattern... urlpatterns = patterns('', # ... (r'^admin/', include(admin.site.urls)), # ... )
現在django管理工具可以運行了。但是現在只有Groups和Users兩個站點。
二、將新Models加入Admin管理
1、在books目錄下創建一個文件:admin.py,然后輸入代碼:
liuxiaoyan@development:~/mysite/books$ clear liuxiaoyan@development:~/mysite/books$ cat admin.py from django.contrib import admin from books.models import Publisher, Author, Book admin.site.register(Publisher) admin.site.register(Author) admin.site.register(Book)
這些代碼通知管理工具為該模型提供界面。服務重啟就可以看到新增了books站點。
操作界面:
books的外鍵Publisher是用一個下拉選擇框來顯示的。
"多對多"的自動author用一個多選框提醒。
2、Admin工作原理
服務啟動時,Django從"url.py"引導URLconf,然后執行"admin.autodiscover()"語句。這個函數遍歷INSTALLED_APPS配置,並且尋找相關的admin.py文件,如果在指定的app目錄下找到admin.py,就執行其中的代碼。
在"books"應用程序的"admin.py"文件中,每次調用"admin.site.register()"都將那個模塊注冊到管理工具中。管理工具只為那些明確注冊了的模塊顯示一個編輯/修改的界面。
應用程序"django.contrib.auth"包含自身的"admin.py",所以Users和Groups能在管理工具中自動顯示。其他的django.contrib應用程序,如django.contrib.redirects,其他從網上下載的第三方Django應用程序一樣,都會自行添加到管理工具。
綜上所述,管理工具其實就是一個Django應用程序,包含自己的模型、模板、視圖和URLpatterns。
三、自定義管理頁面模塊
1、設置字段可選(blank=True)
比如設置email字段可選,編輯Auth模塊(mysite/books/models.py),在email字段加上blank=True。
class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField(blank=True) def __unicode__(self): return u'%s %s' % (self.first_name, self.last_name)
不要重啟服務,刷新瀏覽器即可看到Email:標簽原來是加粗的,現在已經不是粗體了,說明已生效。
2、設置日期類型和數字字段可選(略復雜null=True blank=True)
為了保證數據一致性,django生成的CREATE TABLE語句自動為每個字段顯示加上NOT NULL。這種做法在你給一個字段留空時,會插入一個空字符串(而非NULL)。
但是,其他數據類型有禮物:日期型、時間型和數字型字段不接受空字符串。這種情況NULL是唯一指定空值的方法。在Django模塊中,可以通過添加null=True來指定一個字段允許NULL。
所以重點來了,想要允許一個日期型(DateField、TimeField、DateTimeField)或者數字型(IntegerField、DecimalField、FloatField)字段為空,需要同時使用null=True和blank=True。
添加null=True比添加blank=True復雜,因為null=True改變了數據的語義,即改變了CREATE TABLE語句,把publication_date字段上的NOT NULL刪除了。所以要更新數據庫。
但是Django又不會自動更新數據庫結構。所以必須手動執行ALTERTABLE語句將模塊的改動更新至數據庫。

liuxiaoyan@development:~/mysite$ python manage.py dbshell Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 190627 Server version: 5.5.31-0ubuntu0.12.04.2-log (Ubuntu) Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use lxybooks Database changed mysql> show tables; +----------------------------+ | Tables_in_lxybooks | +----------------------------+ | auth_group | | auth_group_permissions | | auth_message | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | books_author | | books_book | | books_book_authors | | books_publisher | | django_admin_log | | django_content_type | | django_session | +----------------------------+ 14 rows in set (0.00 sec) mysql> alter table books_book change publication_date publication_date date NULL; Query OK, 3 rows affected (0.32 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql>
現在添加book的編輯頁面Publication date:不再是粗體,允許輸入一個空的publication date。
3、管理界面字段標簽重命名(verbose_name)
字段標簽命名默認是根據模塊的字段名稱生成的,規則就是用空格代替下划線,首字母大寫。比如Book模塊的publication_date的標簽是Publication date。
比如將Auther.email的標簽改為e-mail。
class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField(blank=True,verbose_name='e-mail') def __unicode__(self): return u'%s %s' % (self.first_name, self.last_name)
刷新瀏覽器就可以看到
四、自定義管理頁面的外觀(修改模型中的admin.py)
1、自定義管理頁面列表
比如現在的Auther如下,頁面只顯示姓名。
class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField(blank=True,verbose_name='e-mail') def __unicode__(self): return u'%s %s' % (self.first_name, self.last_name)
在此基礎上,添加其他字段,從而改變列表的顯示。比如,在列表中可以看到作者的郵箱地址。如果能按照姓排序就完美了。
為此,為Author模塊定義一個AuthorAdmin類。該類是自定義管理工具的關鍵,其中最基本的一件事是運行你指定列表中的字段。
liuxiaoyan@development:~/mysite/books$ cat admin.py from django.contrib import admin from books.models import Publisher, Author, Book class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') admin.site.register(Publisher) admin.site.register(Author,AuthorAdmin) admin.site.register(Book)
解釋:新建了一個類AuthorAdmin,它是從django.contrib.admmin.ModelAdmin派生出來的子類,保存着一個類的自定義配置,以供管理工具使用。自定義了一項:list_display,它是一個字段名稱的元組,用於顯示列表。
修改了admin.site.register()調用,在Author后面添加了AuthorAdmin。從AuthorAdmin選項注冊Author模塊。這一步很重要,如果不給admin.site.register()加上AuthorAdmin,Django還是使用默認選項,就像Publisher和Book一樣。
現在刷新頁面就能看到:三列分別是名稱,姓氏和郵箱了,看起來就很爽了。
2、添加快速查詢欄
給AuthorAdmin追加search_fields,然后刷新一個查詢欄就華麗麗的出來了。
liuxiaoyan@development:~/mysite/books$ cat admin.py from django.contrib import admin from books.models import Publisher, Author, Book class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') search_fields=('first_name','last_name') admin.site.register(Publisher) admin.site.register(Author,AuthorAdmin) admin.site.register(Book)
3、為books添加一些過濾器(按出版時間過濾書)
照貓畫虎,加函數BookAdmin,有兩個內容,一個list_display,一個list_filter。再給Book注冊加上BookAdmin。
liuxiaoyan@development:~/mysite/books$ cat admin.py from django.contrib import admin from books.models import Publisher, Author, Book class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') search_fields=('first_name','last_name') class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) admin.site.register(Publisher) admin.site.register(Author,AuthorAdmin) admin.site.register(Book,BookAdmin)
還有一種過濾日期的方式,用date_hierarchy選項,在頁面列表頂有一個逐層深入的導航條。

liuxiaoyan@development:~/mysite/books$ cat admin.py from django.contrib import admin from books.models import Publisher, Author, Book class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') search_fields=('first_name','last_name') class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy='publication_date' admin.site.register(Publisher) admin.site.register(Author,AuthorAdmin) admin.site.register(Book,BookAdmin)
4、修改默認排序順序
之前在models.py中添加過
class Meta: ordering=['-publication_date']
來控制排序。在admin.py的BookAdmin中加入ordering=('-publication_date')能達到同樣的效果。

liuxiaoyan@development:~/mysite/books$ vi admin.py from django.contrib import admin from books.models import Publisher, Author, Book class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') search_fields=('first_name','last_name') class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy='publication_date' ordering=('-publication_date',) admin.site.register(Publisher) admin.site.register(Author,AuthorAdmin) admin.site.register(Book,BookAdmin)
5、管理頁面編輯菜單自定義字段順序
字段順序默認是和模塊中定義的一致,比如現在Book的編輯順序是Title,Publisher,Publication date,Authors,改為Title,Author,Publisher,Publication date。

liuxiaoyan@development:~/mysite/books$ cat admin.py from django.contrib import admin from books.models import Publisher, Author, Book class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') search_fields=('first_name','last_name') class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy='publication_date' ordering=('-publication_date',) fields = ('title', 'authors', 'publisher', 'publication_date') admin.site.register(Publisher) admin.site.register(Author,AuthorAdmin) admin.site.register(Book,BookAdmin)
現在刷新就看到作者排在書之后了。
6、管理頁面編輯菜單防止重要字段被修改
一個很實用的功能,防止Book的publication_date被修改
超級簡單,就是不要在fields中列出它。

liuxiaoyan@development:~/mysite/books$ cat admin.py from django.contrib import admin from books.models import Publisher, Author, Book class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') search_fields=('first_name','last_name') class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy='publication_date' ordering=('-publication_date',) fields = ('title', 'authors', 'publisher',) admin.site.register(Publisher) admin.site.register(Author,AuthorAdmin) admin.site.register(Book,BookAdmin)
現在就看不到Publication date了,可以防止被不信任的人更改。
用該界面添加一本新書時,Djagno會將publication_date設置為Null,確保滿足null=True的條件。
我現在插入一條記錄《程序員面試寶典》,可以看到它的Publication date在mysql數據庫中是Null
在界面顯示是None
7、管理頁面編輯菜單自定義多對多字段
先看一眼默認的多對多字段,books編輯頁面"多對多字段"作者被展現成多選框,當有幾百個作者的選項時,會很糟糕。而且,雖然下面有注釋,但是選擇多個作者很不方便。
現在使用filter_horizontal改進。(注釋掉之前加入的fields選項,加上filter_horizontal)

liuxiaoyan@development:~/mysite/books$ cat admin.py from django.contrib import admin from books.models import Publisher, Author, Book class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') search_fields=('first_name','last_name') class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy='publication_date' ordering=('-publication_date',) filter_horizontal=('authors',) admin.site.register(Publisher) admin.site.register(Author,AuthorAdmin) admin.site.register(Book,BookAdmin)
看到一個精巧的JavaScript過濾器,用戶體驗非常好。
filter_vertical通上,只是控件垂直排列。
8、管理頁面編輯菜單自定義外鍵的修改
filter_horizontal和filter_vertical選項只能用在多對多字段,不能用於外鍵字段。外鍵默認用下拉框展示。
當book可選的出版商多達幾百時,在頁面加載需要很大開銷,時間太久,因為需要把每個publisher都裝載並顯示在"下拉框"中。
解決該問題的辦法是使用"raw_id_fields"選項。它是一個包含外鍵字段名稱的元組,它包含的字段將被展示成"文本框",而不再是"下拉框"。

liuxiaoyan@development:~/mysite/books$ cat admin.py from django.contrib import admin from books.models import Publisher, Author, Book class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') search_fields=('first_name','last_name') class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') list_filter = ('publication_date',) date_hierarchy='publication_date' ordering=('-publication_date',) filter_horizontal=('authors',) raw_id_fields=('publisher',) admin.site.register(Publisher) admin.site.register(Author,AuthorAdmin) admin.site.register(Book,BookAdmin)
效果如下:點這個"放大鏡"圖標就可以打開一個新的頁面來顯示外鍵。
在這個框里輸入是的外鍵的ID號,當然我們不可能去記住這玩意的,所以django提供了放大鏡讓我們選。選名稱自動填入ID號。【//lxy:ps:這用戶體驗我也是醉了!!】
五、用戶、用戶組 和權限
根據需求指定用戶權限,從而用戶部分訪問系統。
用戶對象有標准的用戶名、密碼、郵箱地址和真實姓名,同時它還有關於使用管理界面的權限定義。
活動標志:控制用戶是否已經激活。如果該標記關閉,用戶嘗試登錄即使密碼正確也無法登錄系統。
成員標志:該標志用來區分公眾用戶和管理用戶。即是否可登錄管理界面。
超級用戶標志:有這個標志,其他設置權限都被忽略,用戶可在管理界面添加、修改和刪除任何項目。
管理界面每種對象都有創建許可、編輯許可和刪除許可。
Note:權限管理系統也控制編輯用戶的權限。給用戶編輯用戶的權限,他可以編輯自己的權限,賦予一個用戶修改用戶的權限,本質上說就是把他變成一個超級用戶。
資源鏈接:
http://djangobook.py3k.cn/2.0/chapter06/