日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

編寫(xiě)你的第一個(gè) Django 應(yīng)用,第 7 部分 | Django 文檔 | Django

 寧?kù)o致遠(yuǎn)oj1kn5 2019-06-13

編寫(xiě)你的第一個(gè) Django 應(yīng)用,第 7 部分?

這篇教程承接 教程第 6 部分 結(jié)束的地方。我們繼續(xù)修改在線(xiàn)投票應(yīng)用,這次我們專(zhuān)注于自定義我們?cè)?教程第 2 部分 初見(jiàn)過(guò)的 Django 自動(dòng)生成后臺(tái)的過(guò)程。

自定義后臺(tái)表單?

通過(guò) admin.site.register(Question) 注冊(cè) Question 模型,Django 能夠構(gòu)建一個(gè)默認(rèn)的表單用于展示。通常來(lái)說(shuō),你期望能自定義表單的外觀和工作方式。你可以在注冊(cè)模型時(shí)將這些設(shè)置告訴 Django。

讓我們通過(guò)重排列表單上的字段來(lái)看看它是怎么工作的。用以下內(nèi)容替換 admin.site.register(Question)

polls/admin.py?
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)類(lèi),接著將其作為第二個(gè)參數(shù)傳給 admin.site.register() ——在你需要修改模型的后臺(tái)管理選項(xiàng)時(shí)這么做。

以上修改使得 "Publication date" 字段顯示在 "Question" 字段之前:

Fields have been reordered

這在只有兩個(gè)字段時(shí)顯得沒(méi)啥卵用,但對(duì)于擁有數(shù)十個(gè)字段的表單來(lái)說(shuō),為表單選擇一個(gè)直觀的排序方法就顯得你的針很細(xì)了。

說(shuō)到擁有數(shù)十個(gè)字段的表單,你可能更期望將表單分為幾個(gè)字段集:

polls/admin.py?
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)在的樣子:

Form has fieldsets now

添加關(guān)聯(lián)的對(duì)象?

好了,現(xiàn)在我們有了投票的后臺(tái)頁(yè)。不過(guò),一個(gè) Question 有多個(gè) Choice,但后臺(tái)頁(yè)卻沒(méi)有顯示多個(gè)選項(xiàng)。

好了。

有兩個(gè)方法可以解決這個(gè)問(wèn)題。第一個(gè)就是仿照我們向后臺(tái)注冊(cè) Question 一樣注冊(cè) Choice 。這很簡(jiǎn)單:

polls/admin.py?
from django.contrib import admin

from .models import Choice, Question
# ...
admin.site.register(Choice)

現(xiàn)在 "Choices" 在 Django 后臺(tái)頁(yè)中是一個(gè)可用的選項(xiàng)了?!疤砑舆x項(xiàng)”的表單看起來(lái)像這樣:

Choice admin page

在這個(gè)表單中,"Question" 字段是一個(gè)包含數(shù)據(jù)庫(kù)中所有投票的選擇框。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ì)見(jiàn)到一個(gè)包含“添加投票”的表單。如果你在這個(gè)彈出框中添加了一個(gè)投票,并點(diǎn)擊了“保存”,Django 會(huì)將其保存至數(shù)據(jù)庫(kù),并動(dòng)態(tài)地在你正在查看的“添加選項(xiàng)”表單中選中它。

不過(guò),這是一種很低效地添加“選項(xiàng)”的方法。更好的辦法是在你創(chuàng)建“投票”對(duì)象時(shí)直接添加好幾個(gè)選項(xiàng)。讓我們實(shí)現(xiàn)它。

移除調(diào)用 register() 注冊(cè) Choice 模型的代碼。隨后,像這樣修改 Question 的注冊(cè)代碼:

polls/admin.py?
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)頁(yè)面編輯。默認(rèn)提供 3 個(gè)足夠的選項(xiàng)字段?!?/p>

加載“添加投票”頁(yè)面來(lái)看看它長(zhǎng)啥樣:

Add question page now has choices on it

它看起來(lái)像這樣:有三個(gè)關(guān)聯(lián)的選項(xiàng)插槽——由 extra 定義,且每次你返回任意已創(chuàng)建的對(duì)象的“修改”頁(yè)面時(shí),你會(huì)見(jiàn)到三個(gè)新的插槽。

在三個(gè)插槽的末端,你會(huì)看到一個(gè)“添加新選項(xiàng)”的按鈕。如果你單擊它,一個(gè)新的插槽會(huì)被添加。如果你想移除已有的插槽,可以點(diǎn)擊插槽右上角的X。注意,你不能移除原始的 3 個(gè)插槽。以下圖片展示了一個(gè)已添加的插槽:

Additional slot added dynamically

不過(guò),仍然有點(diǎn)小問(wèn)題。它占據(jù)了大量的屏幕區(qū)域來(lái)顯示所有關(guān)聯(lián)的 Choice 對(duì)象的字段。對(duì)于這個(gè)問(wèn)題,Django 提供了一種表格式的單行顯示關(guān)聯(lián)對(duì)象的方法。你只需按如下形式修改 ChoiceInline 申明:

polls/admin.py?
class ChoiceInline(admin.TabularInline):
    #...

通過(guò) TabularInline``(替代 ``StackedInline ),關(guān)聯(lián)對(duì)象以一種表格式的方式展示,顯得更加緊湊:

Add question page now has more compact choices

注意這里有一個(gè)額外的“刪除?”列,這允許移除通過(guò)“添加新選項(xiàng)”按鈕添加的,或是已被保存的行。

自定義后臺(tái)更改列表?

現(xiàn)在投票的后臺(tái)頁(yè)看起來(lái)很不錯(cuò),讓我們對(duì)“更改列表”頁(yè)面進(jìn)行一些調(diào)整——改成一個(gè)能展示系統(tǒng)中所有投票的頁(yè)面。

以下是它此時(shí)的外觀:

Polls change list page

默認(rèn)情況下,Django 顯示每個(gè)對(duì)象的 str() 返回的值。但有時(shí)如果我們能夠顯示單個(gè)字段,它會(huì)更有幫助。為此,使用 list_display 后臺(tái)選項(xiàng),它是一個(gè)包含要顯示的字段名的元組,在更改列表頁(yè)中以列的形式展示這個(gè)對(duì)象:

polls/admin.py?
class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date')

為了更好用,讓我們也包含 教程第 2 部分 中的 was_published_recently() 方法:

polls/admin.py?
class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date', 'was_published_recently')

現(xiàn)在修改投票的列表頁(yè)看起來(lái)像這樣:

Polls change list page, updated

你可以點(diǎn)擊列標(biāo)題來(lái)對(duì)這些行進(jìn)行排序——除了 was_published_recently 這個(gè)列,因?yàn)闆](méi)有實(shí)現(xiàn)排序方法。順便看下這個(gè)列的標(biāo)題 was_published_recently,默認(rèn)就是方法名(用空格替換下劃線(xiàn)),該列的每行都以字符串形式展示出處。

你可以通過(guò)給這個(gè)方法(在 polls/models.py 中)一些屬性來(lái)達(dá)到優(yōu)化的目的,像這樣:

polls/models.py?
class 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?'

更多關(guān)于這些方法屬性的信息,參見(jiàn) list_display。

再次編輯文件 polls/admin.py,優(yōu)化 Question 變更頁(yè):過(guò)濾器,使用 list_filter。將以下代碼添加至 QuestionAdmin

list_filter = ['pub_date']

這樣做添加了一個(gè)“過(guò)濾器”側(cè)邊欄,允許人們以 pub_date 字段來(lái)過(guò)濾列表:

Polls change list page, updated

展示的過(guò)濾器類(lèi)型取決你你要過(guò)濾的字段的類(lèi)型。因?yàn)?pub_date 是類(lèi) DateTimeField,Django 知道要提供哪個(gè)過(guò)濾器:“任意時(shí)間”,“今天”,“過(guò)去7天”,“這個(gè)月”和“今年”。

這已經(jīng)弄的很好了。讓我們?cè)贁U(kuò)充些功能:

search_fields = ['question_text']

在列表的頂部增加一個(gè)搜索框。當(dāng)輸入待搜項(xiàng)時(shí),Django 將搜索 question_text 字段。你可以使用任意多的字段——由于后臺(tái)使用 LIKE 來(lái)查詢(xún)數(shù)據(jù),將待搜索的字段數(shù)限制為一個(gè)不會(huì)出問(wèn)題大小,會(huì)便于數(shù)據(jù)庫(kù)進(jìn)行查詢(xún)操作。

現(xiàn)在是給你的修改列表頁(yè)增加分頁(yè)功能的好時(shí)機(jī)。默認(rèn)每頁(yè)顯示 100 項(xiàng)。變更頁(yè)分頁(yè), 搜索框, 過(guò)濾器, 日期層次結(jié)構(gòu), 和 列標(biāo)題排序 均以你期望的方式合作運(yùn)行。

自定義后臺(tái)界面和風(fēng)格?

在每個(gè)后臺(tái)頁(yè)頂部顯示“Django 管理員”顯得很滑稽。這只是一串占位文本。

不過(guò),這可以通過(guò) Django 的模板系統(tǒng)很方便的修改。Django 的后臺(tái)由自己驅(qū)動(dòng),且它的交互接口采用 Django 自己的模板系統(tǒng)。

自定義你的 工程的 模板?

在你的工程目錄(指包含 manage.py 的那個(gè)文件夾)內(nèi)創(chuàng)建一個(gè)名為 templates 的目錄。模板可放在你系統(tǒng)中任何 Django 能找到的位置。(誰(shuí)啟動(dòng)了 Django,Django 就以他的用戶(hù)身份運(yùn)行。)不過(guò),把你的模板放在工程內(nèi)會(huì)帶來(lái)很大便利,推薦你這樣做。

打開(kāi)你的設(shè)置文件(mysite/settings.py,牢記),在 TEMPLATES 設(shè)置中添加 DIRS 選項(xiàng):

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 是一個(gè)包含多個(gè)系統(tǒng)目錄的文件列表,用于在載入 Django 模板時(shí)使用,是一個(gè)待搜索路徑。

組織模板

就像靜態(tài)文件一樣,我們 可以 把所有的模板文件放在一個(gè)大模板目錄內(nèi),這樣它也能工作的很好。但是,屬于特定應(yīng)用的模板文件最好放在應(yīng)用所屬的模板目錄(例如 polls/templates),而不是工程的模板目錄(templates)。我們會(huì)在 創(chuàng)建可復(fù)用的應(yīng)用教程 中討論 為什么 我們要這樣做。

現(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)。

Django 的源文件在哪里?

如果你不知道 Django 源碼在你系統(tǒng)的哪個(gè)位置,運(yùn)行以下命令:

$ python -c "import django; print(django.__path__)"
...\> py -c "import django; print(django.__path__)"

接著,用你站點(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è)方法來(lái)教你復(fù)寫(xiě)模板。在一個(gè)實(shí)際工程中,你可能更期望使用 django.contrib.admin.AdminSite.site_header 來(lái)進(jìn)行簡(jiǎn)單的定制。

這個(gè)模板文件包含很多類(lèi)似 {% block branding %}{{ title }} 的文本。 {%{{ 標(biāo)簽是 Django 模板語(yǔ)言的一部分。當(dāng) Django 渲染 admin/base_site.html 時(shí),這個(gè)模板語(yǔ)言會(huì)被求值,生成最終的網(wǎng)頁(yè),就像我們?cè)?教程第 3 部分 所學(xué)的一樣。

注意,所有的 Django 默認(rèn)后臺(tái)模板均可被復(fù)寫(xiě)。若要復(fù)寫(xiě)模板,像你修改 base_site.html 一樣修改其它文件——先將其從默認(rèn)目錄中拷貝到你的自定義目錄,再做修改。

自定義你 應(yīng)用的 模板?

機(jī)智的同學(xué)可能會(huì)問(wèn): 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ù)雜,所以無(wú)需自定義后臺(tái)模板。不過(guò),如果它變的更加復(fù)雜,需要修改 Django 的標(biāo)準(zhǔn)后臺(tái)模板功能時(shí),修改 應(yīng)用 的模板會(huì)比 工程 的更加明智。這樣,在其它工程包含這個(gè)投票應(yīng)用時(shí),可以確保它總是能找到需要的自定義模板文件。

更多關(guān)于 Django 如何查找模板的文檔,參見(jiàn) 加載模板文檔。

自定義后臺(tái)主頁(yè)?

在類(lèi)似的說(shuō)明中,你可能想要自定義 Django 后臺(tái)索引頁(yè)的外觀。

默認(rèn)情況下,它展示了所有配置在 INSTALLED_APPS 中,已通過(guò)后臺(tái)應(yīng)用注冊(cè),按拼音排序的應(yīng)用。你可能想對(duì)這個(gè)頁(yè)面的布局做重大的修改。畢竟,索引頁(yè)是后臺(tái)的重要頁(yè)面,它應(yīng)該便于使用。

需要自定義的模板是 admin/index.html。(像上一節(jié)修改 admin/base_site.html 那樣修改此文件——從默認(rèn)目錄中拷貝此文件至自定義模板目錄)。打開(kāi)此文件,你將看到它使用了一個(gè)叫做 app_list 的模板變量。這個(gè)變量包含了每個(gè)安裝的 Django 應(yīng)用。你可以用任何你期望的硬編碼鏈接(鏈接至特定對(duì)象的管理頁(yè))替代使用這個(gè)變量。

接下來(lái)要做什么??

初學(xué)者教程到這就結(jié)束了。隨后,你可能想閱讀 下一步看什么,看看下一步能做什么。

如果你很熟悉 Python 打包,且對(duì)學(xué)習(xí)如何把投票應(yīng)用改成“可復(fù)用應(yīng)用”感興趣,查看 進(jìn)階教程:如何創(chuàng)建可復(fù)用應(yīng)用

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多