W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
通過 ?admin.site.register(Question)
? 注冊(cè) ?Question
?模型,Django 能夠構(gòu)建一個(gè)默認(rèn)的表單用于展示。通常來說,你期望能自定義表單的外觀和工作方式。你可以在注冊(cè)模型時(shí)將這些設(shè)置告訴 Django。
讓我們通過重排列表單上的字段來看看它是怎么工作的。用以下內(nèi)容替換 ?admin.site.register(Question)
?:
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fields = ['pub_date', 'question_text']
admin.site.register(Question, QuestionAdmin)
你需要遵循以下流程——?jiǎng)?chuàng)建一個(gè)模型后臺(tái)類,接著將其作為第二個(gè)參數(shù)傳給 ?admin.site.register()
?——在你需要修改模型的后臺(tái)管理選項(xiàng)時(shí)這么做。
以上修改使得 "Publication date" 字段顯示在 "Question" 字段之前:
只有兩個(gè)字段并不令人印象深刻,但對(duì)于具有數(shù)十個(gè)字段的管理表單,選擇直觀的順序是一個(gè)重要的可用性細(xì)節(jié)。
說到具有數(shù)十個(gè)字段的表單,您可能希望將表單拆分為字段集:
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]
admin.site.register(Question, QuestionAdmin)
?fieldsets
元組中的第一個(gè)元素是字段集的標(biāo)題。以下是我們的表單現(xiàn)在的樣子:
好了,現(xiàn)在我們有了投票的后臺(tái)頁。不過,一個(gè) ?Question
?有多個(gè) ?Choice
?,但后臺(tái)頁卻沒有顯示多個(gè)選項(xiàng)。
有兩個(gè)方法可以解決這個(gè)問題。第一個(gè)就是仿照我們向后臺(tái)注冊(cè) ?Question
?一樣注冊(cè) ?Choice
?:
from django.contrib import admin
from .models import Choice, Question
# ...
admin.site.register(Choice)
現(xiàn)在 "Choices" 在 Django 后臺(tái)頁中是一個(gè)可用的選項(xiàng)了。“添加選項(xiàng)”的表單看起來像這樣:
在這個(gè)表單中,"Question" 字段是一個(gè)包含數(shù)據(jù)庫中所有投票的選擇框。Django 知道要將 ?ForeignKey
在后臺(tái)中以選擇框 ?<select>
? 的形式展示。此時(shí),我們只有一個(gè)投票。
同時(shí)也注意下 "Question" 旁邊的“添加”按鈕。每個(gè)使用 ?ForeignKey
?關(guān)聯(lián)到另一個(gè)對(duì)象的對(duì)象會(huì)自動(dòng)獲得這個(gè)功能。當(dāng)你點(diǎn)擊“添加”按鈕時(shí),你會(huì)見到一個(gè)包含“添加投票”的表單。如果你在這個(gè)彈出框中添加了一個(gè)投票,并點(diǎn)擊了“保存”,Django 會(huì)將其保存至數(shù)據(jù)庫,并動(dòng)態(tài)地在你正在查看的“添加選項(xiàng)”表單中選中它。
不過,這是一種很低效地添加“選項(xiàng)”的方法。更好的辦法是在你創(chuàng)建“投票”對(duì)象時(shí)直接添加好幾個(gè)選項(xiàng)。讓我們實(shí)現(xiàn)它。
移除調(diào)用 ?register()
? 注冊(cè) ?Choice
?模型的代碼。隨后,像這樣修改 ?Question
?的注冊(cè)代碼:
from django.contrib import admin
from .models import Choice, Question
class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)
這會(huì)告訴 Django:“?Choice
?對(duì)象要在 ?Question
?后臺(tái)頁面編輯。默認(rèn)提供 3 個(gè)足夠的選項(xiàng)字段?!?br>加載“添加投票”頁面來看看它長啥樣:
它看起來像這樣:有三個(gè)關(guān)聯(lián)的選項(xiàng)插槽——由 ?extra
?定義,且每次你返回任意已創(chuàng)建的對(duì)象的“修改”頁面時(shí),你會(huì)見到三個(gè)新的插槽。
在三個(gè)插槽的末端,你會(huì)看到一個(gè)“添加新選項(xiàng)”的按鈕。如果你單擊它,一個(gè)新的插槽會(huì)被添加。如果你想移除已有的插槽,可以點(diǎn)擊插槽右上角的X。以下圖片展示了一個(gè)已添加的插槽:
不過,仍然有點(diǎn)小問題。它占據(jù)了大量的屏幕區(qū)域來顯示所有關(guān)聯(lián)的 ?Choice
?對(duì)象的字段。對(duì)于這個(gè)問題,Django 提供了一種表格式的單行顯示關(guān)聯(lián)對(duì)象的方法。要使用它,只需按如下形式修改 ?ChoiceInline
?申明:
class ChoiceInline(admin.TabularInline):
#...
通過 ?TabularInline
?(替代 ?StackedInline
?),關(guān)聯(lián)對(duì)象以一種表格式的方式展示,顯得更加緊湊:
注意這里有一個(gè)額外的“刪除”列,這允許移除通過“添加新選項(xiàng)”按鈕添加的,或是已被保存的行。
現(xiàn)在投票的后臺(tái)頁看起來很不錯(cuò),讓我們對(duì)“更改列表”頁面進(jìn)行一些調(diào)整——改成一個(gè)能展示系統(tǒng)中所有投票的頁面。
以下是它此時(shí)的外觀:
默認(rèn)情況下,Django 顯示每個(gè)對(duì)象的 ?str()
? 返回的值。但有時(shí)如果我們能夠顯示單個(gè)字段,它會(huì)更有幫助。為此,使用 ?list_display
?后臺(tái)選項(xiàng),它是一個(gè)包含要顯示的字段名的元組,在更改列表頁中以列的形式展示這個(gè)對(duì)象:
class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ('question_text', 'pub_date')
另外,讓我們把 教程第 2 部分 中的 ?was_published_recently()
? 方法也加上:
class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ('question_text', 'pub_date', 'was_published_recently')
現(xiàn)在修改投票的列表頁看起來像這樣:
你可以點(diǎn)擊列標(biāo)題來對(duì)這些行進(jìn)行排序——除了 ?was_published_recently
?這個(gè)列,因?yàn)闆]有實(shí)現(xiàn)排序方法。順便看下這個(gè)列的標(biāo)題 ?was_published_recently
?,默認(rèn)就是方法名(用空格替換下劃線),該列的每行都以字符串形式展示出處。
你可以通過在該方法上(在 ?polls/models.py
? 中)使用 ?display()
? 裝飾器來改進(jìn),如下圖所示:
from django.contrib import admin
class Question(models.Model):
# ...
@admin.display(
boolean=True,
ordering='pub_date',
description='Published recently?',
)
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
再次編輯文件 ?polls/admin.py
?,優(yōu)化 ?Question
變更頁:過濾器,使用 ?list_filter
?。將以下代碼添加至 ?QuestionAdmin
?:
list_filter = ['pub_date']
這樣做添加了一個(gè)“過濾器”側(cè)邊欄,允許人們以 ?pub_date
?字段來過濾列表:
展示的過濾器類型取決你你要過濾的字段的類型。因?yàn)??pub_date
?是類 ?DateTimeField
?,Django 知道要提供哪個(gè)過濾器:“任意時(shí)間”,“今天”,“過去7天”,“這個(gè)月”和“今年”。
這已經(jīng)弄的很好了。讓我們?cè)贁U(kuò)充些功能:
search_fields = ['question_text']
在列表的頂部增加一個(gè)搜索框。當(dāng)輸入待搜項(xiàng)時(shí),?Django ?將搜索 ?question_text
?字段。你可以使用任意多的字段——由于后臺(tái)使用 ?LIKE
?來查詢數(shù)據(jù),將待搜索的字段數(shù)限制為一個(gè)不會(huì)出問題大小,會(huì)便于數(shù)據(jù)庫進(jìn)行查詢操作。
現(xiàn)在是給你的修改列表頁增加分頁功能的好時(shí)機(jī)。默認(rèn)每頁顯示 100 項(xiàng)。變更頁分頁, 搜索框, 過濾器, 日期層次結(jié)構(gòu), 和 列標(biāo)題排序 均以你期望的方式合作運(yùn)行。
在每個(gè)后臺(tái)頁頂部顯示“Django 管理員”顯得很滑稽。這只是一串占位文本。
不過,你可以通過 Django 的模板系統(tǒng)來修改。Django 的后臺(tái)由自己驅(qū)動(dòng),且它的交互接口采用 Django 自己的模板系統(tǒng)。
在你的工程目錄(指包含 ?manage.py
? 的那個(gè)文件夾)內(nèi)創(chuàng)建一個(gè)名為 ?templates
?的目錄。模板可放在你系統(tǒng)中任何 Django 能找到的位置。(誰啟動(dòng)了 Django,Django 就以他的用戶身份運(yùn)行。)不過,把你的模板放在工程內(nèi)會(huì)帶來很大便利,推薦你這樣做。
打開你的設(shè)置文件(?mysite/settings.py
?,牢記),在 ?TEMPLATES
?設(shè)置中添加 ?DIRS
?選項(xiàng):
?
DIRS
?中只需填寫模板路徑即可
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [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
?是一個(gè)包含多個(gè)系統(tǒng)目錄的文件列表,用于在載入 Django 模板時(shí)使用,是一個(gè)待搜索路徑。
現(xiàn)在,在 ?templates
?目錄內(nèi)創(chuàng)建名為 ?admin
?的目錄,隨后,將存放 Django 默認(rèn)模板的目錄(?django/contrib/admin/templates
?)內(nèi)的模板文件 ?admin/base_site.html
? 復(fù)制到這個(gè)目錄內(nèi)。
接著,用你網(wǎng)頁站點(diǎn)的名字編輯替換文件內(nèi)的 ?{{ site_header|default:_('Django administration') }}
? (包含大括號(hào))。完成后,你應(yīng)該看到如下代碼:
{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}
我們會(huì)用這個(gè)方法來教你復(fù)寫模板。在一個(gè)實(shí)際工程中,你可能更期望使用 ?django.contrib.admin.AdminSite.site_header
? 來進(jìn)行簡單的定制。
這個(gè)模板文件包含很多類似 ?{% block branding %}
? 和 ?{{ title }}
? 的文本。 ?{%
? 和 ?{{
? 標(biāo)簽是 Django 模板語言的一部分。當(dāng) Django 渲染 ?admin/base_site.html
? 時(shí),這個(gè)模板語言會(huì)被求值,生成最終的網(wǎng)頁,就像我們?cè)?教程第 3 部分 所學(xué)的一樣。
注意,所有的 Django 默認(rèn)后臺(tái)模板均可被復(fù)寫。若要復(fù)寫模板,像你修改 ?base_site.html
? 一樣修改其它文件——先將其從默認(rèn)目錄中拷貝到你的自定義目錄,再做修改。
機(jī)智的同學(xué)可能會(huì)問: ?DIRS
?默認(rèn)是空的,Django 是怎么找到默認(rèn)的后臺(tái)模板的?因?yàn)??APP_DIRS
?被置為 ?True
?,Django 會(huì)自動(dòng)在每個(gè)應(yīng)用包內(nèi)遞歸查找 ?templates/
? 子目錄(不要忘了 ?django.contrib.admin
? 也是一個(gè)應(yīng)用)。
我們的投票應(yīng)用不是非常復(fù)雜,所以無需自定義后臺(tái)模板。不過,如果它變的更加復(fù)雜,需要修改 Django 的標(biāo)準(zhǔn)后臺(tái)模板功能時(shí),修改 應(yīng)用 的模板會(huì)比 工程 的更加明智。這樣,在其它工程包含這個(gè)投票應(yīng)用時(shí),可以確保它總是能找到需要的自定義模板文件。
在類似的說明中,你可能想要自定義 Django 后臺(tái)索引頁的外觀。
默認(rèn)情況下,它展示了所有配置在 ?INSTALLED_APPS
?中,已通過后臺(tái)應(yīng)用注冊(cè),按拼音排序的應(yīng)用。你可能想對(duì)這個(gè)頁面的布局做重大的修改。畢竟,索引頁是后臺(tái)的重要頁面,它應(yīng)該便于使用。
需要自定義的模板是 ?admin/index.html
?。(像上一節(jié)修改 ?admin/base_site.html
? 那樣修改此文件——從默認(rèn)目錄中拷貝此文件至自定義模板目錄)。打開此文件,你將看到它使用了一個(gè)叫做 ?app_list
?的模板變量。這個(gè)變量包含了每個(gè)安裝的 Django 應(yīng)用。你可以用任何你期望的硬編碼鏈接(鏈接至特定對(duì)象的管理頁)替代使用這個(gè)變量。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: