Django後臺管理界面

以前的幾篇記錄了模板視圖、模型等頁面展現的相關內容,這篇主要寫一下後臺admin管理界面的內容。html

激活管理界面

Django管理站點徹底是可選擇的,以前咱們是把這些功能給屏蔽掉了。記得上篇中Django模型模型安裝小結中,咱們把settings.py中的部份內容屏蔽了,並添加了一個app,以下python

 1 INSTALLED_APPS = (
 2 ##    'django.contrib.admin',
 3 ##    'django.contrib.auth',
 4 ##    'django.contrib.contenttypes',
 5 ##    'django.contrib.sessions',
 6 ##    'django.contrib.messages',
 7 ##    'django.contrib.staticfiles',
 8     'mysite.books',
 9 )
10 
11 MIDDLEWARE_CLASSES = (
12 ##    'django.contrib.sessions.middleware.SessionMiddleware',
13 ##    'django.middleware.common.CommonMiddleware',
14 ##    'django.middleware.csrf.CsrfViewMiddleware',
15 ##    'django.contrib.auth.middleware.AuthenticationMiddleware',
16 ##    'django.contrib.messages.middleware.MessageMiddleware',
17 ##    'django.middleware.clickjacking.XFrameOptionsMiddleware',
18 )

django.contrib.admin等這些就是支持後臺admin管理界面的app,咱們將上邊這些註釋所有去掉,便可增長對後臺管理界面的支持。shell

運行 python manage.py syncdb 。這一步將生成管理界面使用的額外數據庫表。 當你把'django.contrib.auth'加進INSTALLED_APPS後,第一次運行syncdb命令時, 系統會請你建立一個超級用戶。 若是你不這麼做,你須要運行python manage.py createsuperuser來另外建立一個admin的用戶賬號,不然你將不能登入admin (提醒一句: 只有當INSTALLED_APPS包含'django.contrib.auth'時,python manage.py createsuperuser這個命令纔可用.)數據庫

到這裏,咱們就把後臺管理基本配置好了。可是想一想,咱們還差什麼沒作?django

時刻記得,去urls.py進行配置哦,下圖是新建的project初始時候的URLConf,在Django創建helloworld自定義頁面裏咱們刪除掉的內容session

 1 from django.conf.urls import patterns, include, url
 2 
 3 from django.contrib import admin
 4 
 5 admin.autodiscover()
 6 
 7 urlpatterns = patterns('',
 8     # Examples:
 9     # url(r'^$', 'testsite.views.home', name='home'),
10     # url(r'^blog/', include('blog.urls')),
11 
12     url(r'^admin/', include(admin.site.urls)),
13                        
14 )

如今,咱們要訪問admin了,添加回來這幾句吧app

from django.contrib import admin
admin.autodiscover()
url(r'^admin/', include(admin.site.urls)),

好,咱們運行起來看看吧。效果以下:函數

輸入以前你添加的管理員帳戶和密碼,登錄網站後臺看看吧工具

若是你的母語不是英語,你能夠作一個快速更改來觀察Django管理工具是否被翻譯成你想要的語言。 僅需添加 ‘django.middleware.locale.LocaleMiddleware’ 到 MIDDLEWARE_CLASSES 設置中,並確保它在’django.contrib.sessions.middleware.SessionMiddleware’後邊(其實前後是不要緊的)。以下我放在了第一個位置。post

1 MIDDLEWARE_CLASSES = (
2     'django.middleware.locale.LocaleMiddleware',
3     'django.contrib.sessions.middleware.SessionMiddleware',
4     'django.middleware.common.CommonMiddleware',
5     'django.middleware.csrf.CsrfViewMiddleware',
6     'django.contrib.auth.middleware.AuthenticationMiddleware',
7     'django.contrib.messages.middleware.MessageMiddleware',
8     'django.middleware.clickjacking.XFrameOptionsMiddleware',
9 )

刷新一個剛纔的頁面,看看效果。

具體的使用,無非就是增刪改查了,本身去點吧。

將自定義的Models加入到Admin管理中

上一篇Django模型-數據庫操做,咱們定義了三個模塊:Publisher 、 Author 和 Book 。 讓咱們將本身的模塊加入管理工具中,這樣咱們就可以經過這個後臺管理界面添加、修改和刪除數據庫中的對象了。

還記得新建的books app初始化的幾個文件嗎?

打開admin.py,添加內容以下

1 from django.contrib import admin
2 
3 # Register your models here.
4 from mysite.books.models import Publisher, Author, Book
5 
6 admin.site.register(Publisher)
7 admin.site.register(Author)
8 admin.site.register(Book)

這些代碼通知管理工具爲這些模塊逐一提供界面。你可能須要先中止,而後再啓動服務(runserver),才能使其生效。

 點開新加的三個模塊,點開Books,外鍵publisher用一個選擇框顯示,多對多字段author用一個多選框顯示,日期字段也是datepicker樣式的選擇,有沒有很強大。

Admin是如何工做的

當服務啓動時,Django從urls.py引導URLconf,而後執行admin.autodiscover()語句。 這個函數遍歷INSTALLED_APPS配置,而且尋找相關的 admin.py文件。 若是在指定的app目錄下找到admin.py,它就執行其中的代碼。 

在books應用程序目錄下的admin.py文件中,每次調用admin.site.register()都將那個模塊註冊到管理工具中。 管理工具只爲那些明確註冊了的模塊顯示一個編輯/修改的界面。 

應用程序django.contrib.auth包含自身的admin.py,因此Users和Groups能在管理工具中自動顯示。 

字段設置

咱們嘗試添加一個做者信息,發現一些現象,每一個字段都是必填項,Email也有專門的格式驗證。若是咱們不想要這些限制,該怎麼作呢?

修改咱們的models.py以下

1 class Author(models.Model):
2     first_name = models.CharField(max_length=30)
3     last_name = models.CharField(max_length=40)
4     email = models.EmailField(blank=True)
5     
6     def __unicode__(self):
7         return u'%s %s' % (self.first_name,self.last_name)

標紅部分是新添加的屬性,這些代碼告訴Django,做者的郵箱地址容許輸入一個空值。

全部字段都默認blank=False,這使得它們不容許輸入空值。

刷新頁面,將會發現Email的標籤再也不是粗體,這意味它不是一個必填字段。

 針對日期和數字的設置

Django生成CREATE TABLE語句自動爲每一個字段顯式加上NOT NULL,在大多數狀況下,這種默認的行爲對你的應用程序來講是最佳的(消除NULL和空字符串的數據不一致)。

可是,其它數據類型有例外:日期型、時間型和數字型字段不接受空字符串。 若是你嘗試將一個空字符串插入日期型或整數型字段,你可能會獲得數據庫返回的錯誤,這取決於那個數據庫的類型。 (PostgreSQL比較嚴禁,會拋出一個異常;MySQL可能會也可能不會接受,這取決於你使用的版本和運氣了。)在這種狀況下,NULL是惟一指定空值的方法。 在Django模塊中,你能夠經過添加null=True來指定一個字段容許爲NULL

若是你想容許一個日期型(DateFieldTimeFieldDateTimeField)或數字型(IntegerFieldDecimalFieldFloatField)字段爲空,你須要使用null=True  和 blank=True

添加null=True比添加blank=True複雜。由於null=True改變了數據的語義,即改變了CREATE TABLE語句,把publication_date字段上的NOT NULL刪除了。 要完成這些改動,咱們還須要更新數據庫。然而Django不會嘗試自動更新數據庫結構,因此你必須執行ALTER TABLE語句將模塊的改動更新至數據庫。

使用manage.py dbshell進入數據庫服務環境,執行命令

ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;

如今回到管理工具,添加book的編輯頁面就容許輸入一個空的publication date。

 日期和數字的設置這部分,因爲我本地環境問題,manage.py  dbshell總有問題,因此該部份內容,我沒進行相應操做。
 我本地的搜索路徑以下,是否是缺乏Sqlite3的命令路徑?有大牛知道的,請告知,謝謝! 

自定義字段標籤

在編輯頁面中,每一個字段的標籤都是從模塊的字段名稱生成的。規則很簡答:用空格替換下劃線;首字母大寫。好比上邊新增做者的那個截圖:first_name變成了First name。

有些狀況下,咱們想展現自定的標籤名。爲作到這個,咱們只須要在models的模塊定義中指定verbose_name便可。

好比咱們要將Author.email的標籤改爲e-mail,中間有個橫線,能夠這樣作

1 class Author(models.Model):
2     first_name = models.CharField(max_length=30)
3     last_name = models.CharField(max_length=40)
4     email = models.EmailField(blank=True,verbose_name='e-mail')

從新啓動服務,刷新頁面,效果以下

最後還需注意的是,爲了使語法簡潔,你能夠把它看成固定位置的參數傳遞。 這個例子與上面那個的效果相同。
1 class Author(models.Model):
2     first_name = models.CharField(max_length=30)
3     last_name = models.CharField(max_length=40)
4     email = models.EmailField('e-mail',  blank=True)

但這不適用於ManyToManyField 和ForeignKey字段,由於它們第一個參數必須是模塊類。 那種情形,必須顯式使用verbose_name這個參數名稱。

自定義ModelAdmin類

咱們作的 blank=Truenull=Trueverbose_name修改實際上是模塊級別,而不是管理級別的。 也就是說,這些修改實質上是構成模塊的一部分,而且正好被管理工具使用,而不是專門針對管理工具的。除了這些,Django還提供了大量選項讓你針對特別的模塊自定義管理工具。 這些選項都在 ModelAdmin classes裏面,這些類包含了管理工具中針對特別模塊的配置。

自定義列表

讓咱們更深一步:自定義 Author模塊的列表中的顯示字段。 列表默認地顯示查詢結果中對象的 __unicode__()
1 class Author(models.Model):
2     first_name = models.CharField(max_length=30)
3     last_name = models.CharField(max_length=40)
4     email = models.EmailField(blank=True,verbose_name='e-mail')
5 
6     def __unicode__(self):
7         return u'%s %s' % (self.first_name,self.last_name)

咱們能夠在這基礎上改進,添加其它字段,從而改變列表的顯示。 這個頁面應該提供便利,好比說:在這個列表中能夠看到做者的郵箱地址。若是能按照姓氏或名字來排序,那就更好了。

爲了達到這個目的,咱們將爲Author模塊定義一個ModelAdmin類。 這個類是自定義管理工具的關鍵,其中最基本的一件事情是容許你指定列表中的字段。 打開admin.py並修改:

 1 from django.contrib import admin
 2 from models import *
 3 
 4 # Register your models here.
 5 
 6 class AuthorAdmin(admin.ModelAdmin):
 7     list_display = ('first_name', 'last_name', 'email')
 8     
 9 admin.site.register(Publisher)
10 admin.site.register(Author,AuthorAdmin)
11 admin.site.register(Book)

咱們新建了一個類AuthorAdmin,它是從django.contrib.admin.ModelAdmin派生出來的子類,保存着一個類的自定義配置,以供管理工具使用。 咱們只自定義了一項:list_display, 它是一個字段名稱的元組,用於列表顯示。 固然,這些字段名稱必須是模塊中有的

咱們修改了 admin.site.register()調用,在 Author後面添加了 AuthorAdmin。你能夠這樣理解: 用 AuthorAdmin選項註冊 Author模塊。
admin.site.register()函數接受一個 ModelAdmin子類做爲第二個參數。 若是你忽略第二個參數,Django將使用默認的選項。 PublisherBook的註冊就屬於這種狀況。
 
刷新author列表頁面,你會看到列表中有三列:姓氏、名字和郵箱地址。 另外,點擊每一個列的列頭能夠對那列進行排序。
 
讓咱們再添加一個快速查詢欄。 向 AuthorAdmin追加 search_fields,如:
1 class AuthorAdmin(admin.ModelAdmin):
2     list_display = ('first_name', 'last_name', 'email')
3     search_fields = ('first_name', 'last_name')

刷新頁面,效果以下

 
接下來,爲Book列表頁添加一些過濾器,以下
 1 from django.contrib import admin
 2 from models import *
 3 
 4 # Register your models here.
 5 
 6 class AuthorAdmin(admin.ModelAdmin):
 7     list_display = ('first_name', 'last_name', 'email')
 8     search_fields = ('first_name', 'last_name')
 9 
10 class BookAdmin(admin.ModelAdmin):
11     list_display=('title','publisher','publication_date')
12     list_filter=('publication_date',)
13     
14 admin.site.register(Publisher)
15 admin.site.register(Author,AuthorAdmin)
16 admin.site.register(Book,BookAdmin)

刷新效果以下:

list_filter這個字段元組建立過濾器,它位於列表頁面的右邊。 Django爲日期型字段提供了快捷過濾方式,它包含:今天、過往七天、當月和今年。
另一種過濾日期的方式是使用 date_hierarchy選項,如:
1 class BookAdmin(admin.ModelAdmin):
2     list_display=('title','publisher','publication_date')
3     list_filter=('publication_date',)
4     date_hierarchy = 'publication_date'

修改好後,頁面中的列表頂端會有一個逐層深刻的導航條,效果如圖 6-11. 它從可用的年份開始,而後逐層細分到月乃至日。

查看結果以下

請注意, date_hierarchy接受的是* 字符串* ,而不是元組。由於只能對一個日期型字段進行層次劃分。
 
最後,讓咱們改變默認的排序方式,按publication date降序排列。 列表頁面默認按照模塊 class Meta中的 ordering所指的列排序。詳細請看 Django模型-數據庫操做 。該實例中沒有指定ordering,因此排序是沒定義的。
1 class BookAdmin(admin.ModelAdmin):
2     list_display=('title','publisher','publication_date')
3     list_filter=('publication_date',)
4     date_hierarchy = 'publication_date'
5     ordering = ('-publication_date',)

這個ordering選項基本像模塊中class Metaordering那樣工做。效果是Publication date列頭如今有一個小箭頭顯示排序。

自定義編輯表單

首先,咱們先自定義字段順序。 默認地,表單中的字段順序是與模塊中定義是一致的。 咱們能夠經過使用ModelAdmin子類中的fields選項來改變它:

1 class BookAdmin(admin.ModelAdmin):
2     list_display=('title','publisher','publication_date')
3     list_filter=('publication_date',)
4     date_hierarchy = 'publication_date'
5     ordering = ('-publication_date',)
6     fields = ('authors', 'title', 'publisher')

順序是咱們自定義的,可編輯的字段也是咱們可選擇的。效果以下:

此時新增記錄,Django會簡單地將publication_date設置爲None,以確保這個字段知足null=True的條件。

由於以前我說的,本地的Python manage.py dbshell 失敗,致使我沒法修改數據庫結構,

publication_date = models.DateField(blank=True,null=True)

這段代碼是失效的,因此我在這裏提交代碼會出錯,以下:

若是你本地的命令沒問題,而且根據以前的說明修改了對應數據庫字段可空(NULL和空字符串),則不會出錯。

另外一個經常使用的編輯頁面自定義是針對多對多字段的。 真如咱們在book編輯頁面看到的那樣, '多對多字段' 被展示成多選框。雖然多選框在邏輯上是最適合的HTML控件,但它卻不那麼好用。 若是你想選擇多項,你必須還要按下Ctrl鍵。 雖然管理工具添加了註釋(help_text),可是當它有幾百個選項時,它依然顯得笨拙。

更好的辦法是使用filter_horizontal。讓咱們把它添加到BookAdmin中,而後看看它的效果。

1 class BookAdmin(admin.ModelAdmin):
2     list_display=('title','publisher','publication_date')
3     list_filter=('publication_date',)
4     date_hierarchy = 'publication_date'
5     ordering = ('-publication_date',)
6     #fields = ('authors', 'title', 'publisher')
7     filter_horizontal = ('authors',)

效果以下

ModelAdmin類還支持filter_vertical選項。 它像filter_horizontal那樣工做,除了控件都是垂直排列,而不是水平排列的。

filter_horizontalfilter_vertical選項只能用在多對多字段 上, 而不能用於 ForeignKey字段。 默認地,管理工具使用'下拉框' 來展示 外鍵 字段。下拉框選擇就會將全部值加載到下拉列表,選中某個或許須要拖滾動條很久才能找到。

Django提供了raw_id_fields 選項,它是一個包含外鍵字段名稱的元組,它包含的字段將被展示成’ 文本框‘和檢索按鈕的形式。

1 class BookAdmin(admin.ModelAdmin):
2     list_display=('title','publisher','publication_date')
3     list_filter=('publication_date',)
4     date_hierarchy = 'publication_date'
5     ordering = ('-publication_date',)
6     #fields = ('authors', 'title', 'publisher')
7     filter_vertical = ('authors',)
8     raw_id_fields = ('publisher',)

這個文框內可輸入的值是publisher的id,經過檢索彈框選擇便可。

小結

這篇篇幅較長,內容很多。還有一部分關於權限的東西,這裏很少說了,後臺裏多點點就能理解。

相關文章
相關標籤/搜索