编写你的第一个 Django 应用,第 7 部分
我們繼續(xù)修改在線投票應(yīng)用,這次專注于自定義之前見過的 Django 自動生成的Admin界面。
Django7.自定義Admin界面
自定義后臺表單
通過 admin.site.register(Question) 注冊 Question 模型,Django 能夠構(gòu)建一個默認的表單用于展示。
通常來說,我們都希望可以自定義表單的外觀和工作方式,在注冊模型的時候就要將這些設(shè)置告訴 Django。
首先,讓我們通過重新排列表單上的字段來看看它是怎么工作的。
用以下內(nèi)容替換 admin.site.register(Question):
from django.contrib import adminfrom .models import Questionclass QuestionAdmin(admin.ModelAdmin):fields = ['pub_date', 'question_text']admin.site.register(Question, QuestionAdmin)在你需要修改模型的后臺管理選項的時候,首先創(chuàng)建一個模型后臺類,接著將其作為第二個參數(shù)傳給 admin.site.register() 。
以上修改使得 “Publication date” 字段顯示在 “Question” 字段之前:
這在只有兩個字段時顯得沒啥卵用,但對于擁有數(shù)十個字段的表單來說,為表單選擇一個直觀的排序方法就顯得你的針很細了。
說到擁有數(shù)十個字段的表單,你可能更期望將表單分為幾個字段集:
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 元組中的第一個元素是字段集的標題。
以下是我們的表單現(xiàn)在的樣子:
添加關(guān)聯(lián)的對象
好了,現(xiàn)在我們有了投票的后臺頁,不過,一個 Question 有多個 Choice,但后臺頁卻沒有顯示多個選項。
添加選項”的表單看起來像這樣:
在這個表單中,“Question” 字段是一個包含數(shù)據(jù)庫中所有投票的選擇框。Django 知道要將 ForeignKey 在后臺中以選擇框 <select> 的形式展示。
同時也注意下 “Question” 旁邊的“添加”按鈕,每個使用 ForeignKey 關(guān)聯(lián)到另一個對象的對象會自動獲得這個功能,當你點擊“添加”按鈕時,你會見到一個包含“添加投票”的表單。
如果你在這個彈出框中添加了一個投票,并點擊了“保存”,Django 會將其保存至數(shù)據(jù)庫,并動態(tài)地在你正在查看的“添加選項”表單中選中它。
不過,這是一種很低效地添加“選項”的方法,更好的辦法是在你創(chuàng)建“投票”對象時直接添加好幾個選項,讓我們來實現(xiàn)這個需求。
移除調(diào)用 register() 注冊 Choice 模型的代碼,隨后,像這樣修改 Question 的注冊代碼:
from django.contrib import adminfrom .models import Choice, Questionclass ChoiceInline(admin.StackedInline):model = Choiceextra = 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 個足夠的選項字段。”
加載“添加投票”頁面來看看它長啥樣:
有三個關(guān)聯(lián)的選項插槽——由 extra 定義,且每次你返回任意已創(chuàng)建的對象的“修改”頁面時,你會見到三個新的插槽。
在三個插槽的末端,你會看到一個“添加新選項”的按鈕。如果你單擊它,一個新的插槽會被添加。如果你想移除已有的插槽,可以點擊插槽右上角的X。
注意,你不能移除原始的 3 個插槽。
以下圖片展示了一個已添加的插槽:
不過,仍然有點小問題。它占據(jù)了大量的屏幕區(qū)域來顯示所有關(guān)聯(lián)的 Choice 對象的字段。對于這個問題,Django 提供了一種表格式的單行顯示關(guān)聯(lián)對象的方法。要使用它,只需按如下形式修改 ChoiceInline 申明:
class ChoiceInline(admin.TabularInline):#...通過 TabularInline(替代 StackedInline ),關(guān)聯(lián)對象以一種表格式的方式展示,顯得更加緊湊:
注意這里有一個額外的“刪除?”列,這允許移除通過“添加新選項”按鈕添加的,或是已被保存的行。
自定義后臺列表頁面
現(xiàn)在投票的后臺頁看起來很不錯,讓我們對“更改列表”頁面進行一些調(diào)整——改成一個能展示系統(tǒng)中所有投票的頁面。
以下是它此時的外觀:
默認情況下,Django 顯示每個對象的 str() 返回的值。但有時如果我們能夠顯示多個字段,它會更有幫助。
可以使用 list_display 后臺選項,它是一個包含要顯示的字段名的元組,在更改列表頁中以列的形式展示這個對象:
class QuestionAdmin(admin.ModelAdmin):# ...list_display = ('question_text', 'pub_date', 'was_published_recently')現(xiàn)在修改投票的列表頁看起來像這樣:
你可以點擊列標題來對這些行進行排序——除了 was_published_recently 這個列,因為沒有實現(xiàn)排序方法。
順便看下這個列的標題 was_published_recently,默認就是方法名(用空格替換下劃線),該列的每行都以字符串形式展示出處。
你可以通過給這個方法(在 polls/models.py 中)一些屬性來達到優(yōu)化的目的,像這樣:
class Question(models.Model):# ...def was_published_recently(self):now = timezone.now()return now - datetime.timedelta(days=1) <= self.pub_date <= nowwas_published_recently.admin_order_field = 'pub_date'was_published_recently.boolean = Truewas_published_recently.short_description = 'Published recently?'再次編輯文件 polls/admin.py,優(yōu)化 Question 列表頁:過濾器,使用 list_filter。
將以下代碼添加至 QuestionAdmin:
list_filter = ['pub_date']這樣做添加了一個“過濾器”側(cè)邊欄,允許以 pub_date 字段來過濾列表:
展示的過濾器類型取決于你要過濾的字段的類型。因為 pub_date 是 DateTimeField,Django 知道要提供哪個過濾器:“任意時間”,“今天”,“過去7天”,“這個月”和“今年”。
這已經(jīng)弄的很好了,讓我們再擴充些功能,在列表的頂部增加一個搜索框:
search_fields = ['question_text']當輸入待搜項時,Django 將搜索 question_text 字段。
你可以使用任意多的字段——由于后臺使用 LIKE 來查詢數(shù)據(jù),將待搜索的字段數(shù)限制為一個不會出問題大小,會便于數(shù)據(jù)庫進行查詢操作。
Django還提供了很多功能,比如默認每頁顯示 100 項,可以自定義分頁項, 搜索框, 過濾器, 日期層次結(jié)構(gòu), 和 列標題排序 等等,這些功能都是拿來即用的。
自定義后臺界面和風(fēng)格
在每個后臺頁頂部顯示“Django 管理”顯得很不美觀,其實這只是一串占位文本而已。
不過,我們可以通過 Django 的模板系統(tǒng)來修改,Django 的后臺由自己驅(qū)動,且它的交互接口采用 Django 自己的模板系統(tǒng)。
自定義你的 工程的 模板
在你的工程目錄(指包含 manage.py 的那個文件夾)內(nèi)創(chuàng)建一個名為 templates 的目錄,模板可放在你系統(tǒng)中任何 Django 能找到的位置,不過,把你的模板放在工程目錄內(nèi)會帶來很大便利,推薦你這樣做。
打開你的設(shè)置文件(mysite/settings.py,牢記),在 TEMPLATES 設(shè)置中添加 DIRS 選項:
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 是一個包含多個系統(tǒng)目錄的文件列表,用于在載入 Django 模板時使用,是一個待搜索路徑。
組織模板
就像靜態(tài)文件一樣,我們 可以 把所有的模板文件放在一個大模板目錄內(nèi),這樣它也能工作的很好。
但是,屬于特定應(yīng)用的模板文件最好放在應(yīng)用所屬的模板目錄(例如 polls/templates),而不是工程的模板目錄(templates)。
現(xiàn)在,在 templates 目錄內(nèi)創(chuàng)建名為 admin 的目錄,隨后,將存放 Django 默認模板的目錄(django/contrib/admin/templates)內(nèi)的模板文件復(fù)制到這個目錄內(nèi)。
接著,用你網(wǎng)頁站點的名字編輯替換文件base_site內(nèi)的 {{ site_header|default:_('Django administration') }}(包含大括號)。完成后,你應(yīng)該看到如下代碼:
// admin/base_site.html
{% block branding %} <h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1> {% endblock %}這個模板文件包含很多類似 {% block branding %} 和 {{ title }} 的文本。 {% 和 {{ 標簽是 Django 模板語言的一部分,當 Django 渲染 admin/base_site.html 時,這個模板語言會被求值,生成最終的網(wǎng)頁。
注意,所有的 Django 默認后臺模板均可被復(fù)寫,若要復(fù)寫模板,就像剛才修改 base_site.html 一樣修改其它文件即可,當然要先將其從默認目錄中拷貝到你的自定義目錄,再做修改。
自定義你 應(yīng)用的 模板
機智的同學(xué)可能會問:Django 是怎么找到默認的后臺模板的?因為 APP_DIRS 被置為 True,Django 會自動在每個應(yīng)用包內(nèi)遞歸查找 templates/ 子目錄(不要忘了 django.contrib.admin 也是一個應(yīng)用)。
我們的投票應(yīng)用不是非常復(fù)雜,所以無需自定義后臺模板,不過,如果它變的更加復(fù)雜,需要修改 Django 的標準后臺模板功能時,修改 應(yīng)用 的模板會比 工程 的模板更加明智。
這樣,在其它工程包含這個投票應(yīng)用時,可以確保它總是能找到需要的自定義模板文件。
自定義后臺主頁
在類似的說明中,你可能想要自定義 Django 后臺索引頁的外觀。
默認情況下,它展示了所有配置在 INSTALLED_APPS 中,已通過后臺應(yīng)用注冊,按拼音排序的應(yīng)用。
你可能想對這個頁面的布局做重大的修改,畢竟,索引頁是后臺的重要頁面,它應(yīng)該便于使用。
需要自定義的模板是 admin/index.html,打開此文件,你將看到它使用了一個叫做 app_list 的模板變量,這個變量包含了每個安裝的 Django 應(yīng)用。你可以用任何你期望的硬編碼鏈接至特定對象的管理頁,來替代使用這個變量。
好了,我們的第一個Django應(yīng)用就已經(jīng)完成了,從項目創(chuàng)建、數(shù)據(jù)模型、Admin管理頁面、視圖、表單、自動化測試、靜態(tài)文件和這節(jié)課講的自定義后臺,通過Django開發(fā)項目的流程已經(jīng)熟悉了,接下來我們詳細的介紹每一個模塊。
總結(jié)
以上是生活随笔為你收集整理的编写你的第一个 Django 应用,第 7 部分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2013\National _C_C++
- 下一篇: 64. Minimum Path Sum