您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Django項目怎么自定義admin站點,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
一、自定義后臺表單
在前面的學習過程中,通過admin.site.register(Question)語句,我們在admin站點中注冊了Question模型。Django會自動生成一個該模型的默認表單頁面。如果你想自定義該頁面的外觀和工作方式,可以在注冊對象的時候告訴Django你的自定義選項。
下面是一個修改admin表單默認排序方式的例子。修改polls/admin.py的代碼::
from django.contrib import admin from .models import Questionclass QuestionAdmin(admin.ModelAdmin): fields = ['pub_date', 'question_text']admin.site.register(Question, QuestionAdmin)
你只需要創建一個繼承admin.ModelAdmin的模型管理類,然后將它作為第二個參數傳遞給admin.site.register(),第一個參數則是Question模型本身。
上面的修改讓Publication date字段顯示在Question字段前面了(默認是在后面)。如下圖所示:
對于只有2個字段的情況,效果看起來還不是很明顯,但是如果你有一打的字段,選擇一種直觀的符合我們人類習慣的排序方式則非常有用。
還有,當表單含有大量字段的時候,你也許想將表單劃分為一些字段的集合。再次修改polls/admin.py:
from django.contrib import admin from .models import Questionclass QuestionAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date']}), ]admin.site.register(Question, QuestionAdmin)
字段集合fieldsets中每一個元組的第一個元素是該字段集合的標題。它讓我們的頁面看起來像下面的樣子:
二、添加關聯對象
雖然我們已經有了Question的管理頁面,但是一個Question有多個Choices,如果想顯示Choices的內容怎么辦?有兩個辦法可以解決這個問題。第一個是像Question一樣將Choice注冊到admin站點,這很容易,修改polls/admin.py,增加下面的內容:
from django.contrib import adminfrom .models import Choice, Question# ...admin.site.register(Choice)
重啟服務器,再次訪問admin頁面,就可以看到Choice條目了:
點擊它右邊的add按鈕,進入“Add Choice”表單頁面,看起來如下圖:
在這個表單中,Question字段是一個select選擇框,包含了當前數據庫中所有的Question實例。Django在admin站點中,自動地將所有的外鍵關系展示為一個select框。在我們的例子中,目前只有一個question對象存在。
請注意圖中的綠色加號,它連接到Question模型。每一個包含外鍵關系的對象都會有這個綠色加號。點擊它,會彈出一個新增Question的表單,類似Question自己的添加表單。填入相關信息點擊保存后,Django自動將該Question保存在數據庫,并作為當前Choice的關聯外鍵對象。白話講就是,新建一個Question并作為當前Choice的外鍵。
但是實話說,這種創建方式的效率不怎么樣。如果在創建Question對象的時候就可以直接添加一些Choice,那會更好,這就是我們要說的第二種方法。下面,讓我們來動手試試。
首先,刪除polls/admin.py中Choice模型對register()方法的調用。然后,編輯Question的內容,最后整個文件的代碼應該如下:
from django.contrib import adminfrom .models import Choice, Questionclass ChoiceInline(admin.StackedInline): model = Choice extra = 3class QuestionAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline]admin.site.register(Question, QuestionAdmin)
上面的代碼相當于告訴Django,Choice對象將在Question管理頁面進行編輯,默認情況,請提供3個Choice對象的編輯區域。
重啟服務器,進入“Add question”頁面,應該看到如下圖所示:
在3個插槽的最后,還有一個Add another Choice鏈接。點擊它,又可以獲得一個新的插槽。如果你想刪除新增的插槽,點擊它最右邊的灰色X圖標即可。但是,默認的三個插槽不可刪除。
這里還有點小問題。上面頁面中插槽縱隊排列的方式需要占據大塊的頁面空間,查看起來很不方便。為此,Django提供了一種扁平化的顯示方式,你僅僅只需要修改一下ChoiceInline繼承的類為admin.TabularInline替代先前的StackedInline類(其實,從類名上你就能看出兩種父類的區別)。
# polls/admin.pyclass ChoiceInline(admin.TabularInline):
#...
重啟服務器,刷新一下頁面,你會看到類似表格的顯示方式:
注意“DELETE”列,它可以刪除那些已有的Choice和新建的Choice。
三、定制實例的列表頁面
Question的添加和修改頁面我們已經修改得差不多了,下面讓我們來裝飾一下“實例列表”(change list)頁面,該頁面顯示了當前系統中所有的questions實例。
默認情況下,該頁面看起來是這樣的:
通常,Django只顯示__str()__方法指定的內容。但是很多時候,我們可能要同時顯示一些別的內容。要實現這一目的,可以使用list_display屬性,它是一個由字段組成的元組,其中的每一個字段都會按順序顯示在“change list”頁面上,代碼如下:
# polls/admin.pyclass QuestionAdmin(admin.ModelAdmin): # ... list_display = ('question_text', 'pub_date', 'was_published_recently')
額外的,我們把was_published_recently()方法的結果也顯示出來。現在,頁面看起來會是下面的樣子:
你可以點擊每一列的標題,來根據這列的內容進行排序。但是was_published_recently這一列除外,不支持這種根據函數輸出結果進行排序的方式。同時請注意,was_published_recently這一列的列標題默認是方法的名字,內容則是輸出的字符串表示形式。
可以通過給方法提供一些屬性來改進輸出的樣式,如下面所示。注意這次修改的是polls/models.py文件,不要搞錯了!主要是增加了最后面三行內容:
# polls/models.pyclass Question(models.Model): # ... def was_published_recently(self): now = timezone.now() return now - datetime.timedelta(days=1) <= self.pub_date <= now was_published_recently.admin_order_field = 'pub_date' was_published_recently.boolean = True was_published_recently.short_description = 'Published recently?'
重啟服務器(這個我就不再啰嗦了,大家心里都有數)。刷新頁面
以上的定制功能還不是admin的全部,我們接著往下看!
我們還可以對顯示結果進行過濾!使用list_filter屬性,在polls/admin.py的QuestionAdmin中添加下面的代碼:
list_filter = ['pub_date']
再次刷新change list頁面,你會看到在頁面右邊多出了一個基于pub_date的過濾面板,如下圖所示:
根據你選擇的過濾條件的不同,Django會在面板中添加不同的過濾選項。由于pub_date是一個DateTimeField,因此Django自動添加了這些選項:“Any date”, “Today”, “Past 7 days”, “This month”, “This year”。
順理成章的,讓我們添加一些搜索的能力:
search_fields = ['question_text']
這會在頁面的頂部增加一個搜索框。當輸入搜索關鍵字后,Django會在question_text字段內進行搜索。只要你愿意,你可以使用任意多個搜索字段,Django在后臺使用的都是SQL查詢語句的LIKE語法,但是有限制的搜索字段有助于后臺的數據庫查詢效率。
其實,這個頁面還提供分頁功能,默認每頁顯示100條,只是我們的實例只有一個,囧,所以看到分頁鏈接。
四、定制admin整體界面
很明顯,在每一個項目的admin頁面頂端都顯示Django administration是很可笑的,它僅僅是個占位文本。利用Django的模板系統,我們可以快速修改它。
1.定制項目模板
在manage.py文件同級下創建一個templates目錄。然后,打開設置文件mysite/settings.py,在TEMPLATES條目中添加一個DIRS選項:
# mysite/settings.py TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], # 要有這一行,如果已經存在請保持原樣 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
DIRS是一個文件系統目錄的列表,是模板的搜索路徑。當加載Django模板時,會在DIRS中進行查找。
PS:模板的組織方式
就像靜態文件一樣,我們可以把所有的模板都放在一起,形成一個大大的模板文件夾,并且工作正常。但是請一定不要這么做!強烈建議每一個模板都應該存放在它所屬應用的模板目錄內(例如polls/templates)而不是整個項目的模板目錄(templates),因為這樣每個應用才可以被方便和正確的重用。只有對整個項目有作用的模板文件才放在根目錄的templates中,比如admin界面。
回到剛才創建的templates目錄中,再創建一個admin目錄,將admin/base_site.html模板文件拷貝到該目錄內。這個HTML文件來自Django源碼,它位于django/contrib/admin/templates目錄內。 (在我的windows系統中,它位于C:\Python36\Lib\site-packages\django\contrib\admin\templates\admin,請大家參考。)
Django的源代碼在哪里?
如果你無法找到Django源代碼文件的存放位置,可以使用下面的命令:
$ python -c "import django; print(django.__path__)"
編輯base_site.html文件,用你喜歡的站點名字替換掉{{ site_header|default:_(’Django administration’) }}(包括兩個大括號一起替換掉),看起來像下面這樣:
{% extends "admin/base.html" %}{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}{% block branding %}<h2 id="site-name"><a href="{% url 'admin:index' %}">投票站點管理界面</a></h2>{% endblock %}{% block nav-global %}{% endblock %}
在這里,我們使用的是硬編碼,強行改名為"投票站點管理界面"。但是在實際的項目中,你可以使用django.contrib.admin.AdminSite.site_header屬性,方便的對這個頁面title進行自定義。
修改完后,刷新頁面,效果如下:
提示:所有Django默認的admin模板都可以被重寫,類似剛才重寫base_site.html模板的方法一樣,從源代碼目錄將HTML文件拷貝至你自定義的目錄內,然后修改文件。
五、定制admin首頁
默認情況下,admin首頁顯示所有INSTALLED_APPS內并在admin應用中注冊過的app,以字母順序進行排序。
要定制admin首頁,你需要重寫admin/index.html模板,就像前面修改base_site.html模板的方法一樣,從源碼目錄拷貝到你指定的目錄內。編輯該文件,你會看到文件內使用了一個app_list模板變量。該變量包含了所有已經安裝的Django應用。你可以硬編碼鏈接到指定對象的admin頁面,使用任何你認為好的方法,用于替代這個app_list。
六、源碼對照
至此,Django教程的入門部分已經結束了。下面將polls/admin.py的全部代碼貼出來:
from django.contrib import admin from .models import Choice, Questionclass ChoiceInline(admin.TabularInline): model = Choice extra = 3class QuestionAdmin(admin.ModelAdmin): list_display = ('question_text', 'pub_date', 'was_published_recently') fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline] list_filter = ['pub_date'] search_fields = ['question_text']admin.site.register(Question, QuestionAdmin)
整個投票項目mysite,在Pycharm中的文件組織結構如下圖所示,對比一下你自己的,看看是否一樣。
注意2017.png是展示用的背景圖,這個可以不一樣....
admin后臺管理站點可以定制得很強大,比如下面是博主站點的評論后臺,完全手工定制,非常實用!
關于Django項目怎么自定義admin站點就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。