乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Part 7:自定義admin站點(diǎn)

       寧?kù)o致遠(yuǎn)oj1kn5 2019-05-17

      該系列教程系個(gè)人原創(chuàng),并完整發(fā)布在個(gè)人官網(wǎng)劉江的博客和教程

      所有轉(zhuǎn)載本文者,需在頂部顯著位置注明原作者及www.官網(wǎng)地址。


      本節(jié)我們主要介紹在第二部分提到過的admin后臺(tái)管理站點(diǎn)。

      Django的admin站點(diǎn)是自動(dòng)生成的、高度可定制的,它是Django相較其它Web框架獨(dú)有的內(nèi)容,廣受歡迎。如果你覺得它不夠美觀,還有第三方美化版xadmin。請(qǐng)一定不要忽略它,相信我,它值得擁有!

      一、定制模型表單

      在前面的學(xué)習(xí)過程中,通過admin.site.register(Question)語句,我們?cè)赼dmin站點(diǎn)中注冊(cè)了Question模型。Django會(huì)自動(dòng)生成一個(gè)該模型的默認(rèn)表單頁面。如果你想自定義該頁面的外觀和工作方式,可以在注冊(cè)對(duì)象的時(shí)候告訴Django你的自定義選項(xiàng)。

      下面是一個(gè)修改admin表單默認(rèn)排序方式的例子。修改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è)繼承admin.ModelAdmin的模型管理類,然后將它作為第二個(gè)參數(shù)傳遞給admin.site.register(),第一個(gè)參數(shù)則是Question模型本身。

      上面的修改讓Publication date字段顯示在Question字段前面了(默認(rèn)是在后面)。如下圖所示:

      image.png-36.6kB

      對(duì)于只有2個(gè)字段的情況,效果看起來還不是很明顯,但是如果你有一打的字段,選擇一種直觀的符合我們?nèi)祟惲?xí)慣的排序方式則非常有用。

      還有,當(dāng)表單含有大量字段的時(shí)候,你也許想將表單劃分為一些字段的集合。再次修改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è)元組的第一個(gè)元素是該字段集合的標(biāo)題。它讓我們的頁面看起來像下面的樣子:

      image.png-30.1kB

      二、添加關(guān)聯(lián)對(duì)象

      雖然我們已經(jīng)有了Question的管理頁面,但是一個(gè)Question有多個(gè)Choices,如果想顯示Choices的內(nèi)容怎么辦?有兩個(gè)辦法可以解決這個(gè)問題。第一個(gè)是像Question一樣將Choice注冊(cè)到admin站點(diǎn),這很容易,修改polls/admin.py,增加下面的內(nèi)容:

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

      重啟服務(wù)器,再次訪問admin頁面,就可以看到Choice條目了:

      image.png-26.5kB

      點(diǎn)擊它右邊的add按鈕,進(jìn)入“Add Choice”表單頁面,看起來如下圖:

      image.png-18.3kB

      在這個(gè)表單中,Question字段是一個(gè)select選擇框,包含了當(dāng)前數(shù)據(jù)庫(kù)中所有的Question實(shí)例。Django在admin站點(diǎn)中,自動(dòng)地將所有的外鍵關(guān)系展示為一個(gè)select框。在我們的例子中,目前只有一個(gè)question對(duì)象存在。

      請(qǐng)注意圖中的綠色加號(hào),它連接到Question模型。每一個(gè)包含外鍵關(guān)系的對(duì)象都會(huì)有這個(gè)綠色加號(hào)。點(diǎn)擊它,會(huì)彈出一個(gè)新增Question的表單,類似Question自己的添加表單。填入相關(guān)信息點(diǎn)擊保存后,Django自動(dòng)將該Question保存在數(shù)據(jù)庫(kù),并作為當(dāng)前Choice的關(guān)聯(lián)外鍵對(duì)象。白話講就是,新建一個(gè)Question并作為當(dāng)前Choice的外鍵。

      但是實(shí)話說,這種創(chuàng)建方式的效率不怎么樣。如果在創(chuàng)建Question對(duì)象的時(shí)候就可以直接添加一些Choice,那會(huì)更好,這就是我們要說的第二種方法。下面,讓我們來動(dòng)手試試。

      首先,刪除polls/admin.py中Choice模型對(duì)register()方法的調(diào)用。然后,編輯Question的內(nèi)容,最后整個(gè)文件的代碼應(yīng)該如下:

      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)

      上面的代碼相當(dāng)于告訴Django,Choice對(duì)象將在Question管理頁面進(jìn)行編輯,默認(rèn)情況,請(qǐng)?zhí)峁?個(gè)Choice對(duì)象的編輯區(qū)域。

      重啟服務(wù)器,進(jìn)入“Add question”頁面,應(yīng)該看到如下圖所示:

      image.png-40.7kB

      在3個(gè)插槽的最后,還有一個(gè)Add another Choice鏈接。點(diǎn)擊它,又可以獲得一個(gè)新的插槽。如果你想刪除新增的插槽,點(diǎn)擊它最右邊的灰色X圖標(biāo)即可。但是,默認(rèn)的三個(gè)插槽不可刪除。

      這里還有點(diǎn)小問題。上面頁面中插槽縱隊(duì)排列的方式需要占據(jù)大塊的頁面空間,查看起來很不方便。為此,Django提供了一種扁平化的顯示方式,你僅僅只需要修改一下ChoiceInline繼承的類為admin.TabularInline替代先前的StackedInline類(其實(shí),從類名上你就能看出兩種父類的區(qū)別)。

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

      重啟服務(wù)器,刷新一下頁面,你會(huì)看到類似表格的顯示方式:

      image.png-30.2kB

      注意“DELETE”列,它可以刪除那些已有的Choice和新建的Choice。

      三、定制實(shí)例列表頁面

      Question的添加和修改頁面我們已經(jīng)修改得差不多了,下面讓我們來裝飾一下“實(shí)例列表”(change list)頁面,該頁面顯示了當(dāng)前系統(tǒng)中所有的questions實(shí)例。

      默認(rèn)情況下,該頁面看起來是這樣的:

      image.png-31.8kB

      通常,Django只顯示__str()__方法指定的內(nèi)容。但是很多時(shí)候,我們可能要同時(shí)顯示一些別的內(nèi)容。要實(shí)現(xiàn)這一目的,可以使用list_display屬性,它是一個(gè)由字段組成的元組,其中的每一個(gè)字段都會(huì)按順序顯示在“change list”頁面上,代碼如下:

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

      額外的,我們把was_published_recently()方法的結(jié)果也顯示出來?,F(xiàn)在,頁面看起來會(huì)是下面的樣子:

      image.png-28.4kB

      你可以點(diǎn)擊每一列的標(biāo)題,來根據(jù)這列的內(nèi)容進(jìn)行排序。但是was_published_recently這一列除外,不支持這種根據(jù)函數(shù)輸出結(jié)果進(jìn)行排序的方式。同時(shí)請(qǐng)注意,was_published_recently這一列的列標(biāo)題默認(rèn)是方法的名字,內(nèi)容則是輸出的字符串表示形式。

      可以通過給方法提供一些屬性來改進(jìn)輸出的樣式,如下面所示。注意這次修改的是polls/models.py文件,不要搞錯(cuò)了!主要是增加了最后面三行內(nèi)容:

      # 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?'

      重啟服務(wù)器(這個(gè)我就不再啰嗦了,大家心里都有數(shù))。刷新頁面,效果如下:

      image.png-28.8kB

      以上的定制功能還不是admin的全部,我們接著往下看!


      我們還可以對(duì)顯示結(jié)果進(jìn)行過濾!使用list_filter屬性,在polls/admin.py的QuestionAdmin中添加下面的代碼:

      list_filter = ['pub_date']

      再次刷新change list頁面,你會(huì)看到在頁面右邊多出了一個(gè)基于pub_date的過濾面板,如下圖所示:

      image.png-54.6kB

      根據(jù)你選擇的過濾條件的不同,Django會(huì)在面板中添加不同的過濾選項(xiàng)。由于pub_date是一個(gè)DateTimeField,因此Django自動(dòng)添加了這些選項(xiàng):“Any date”, “Today”, “Past 7 days”, “This month”, “This year”。

      順理成章的,讓我們添加一些搜索的能力:

      search_fields = ['question_text']

      這會(huì)在頁面的頂部增加一個(gè)搜索框。當(dāng)輸入搜索關(guān)鍵字后,Django會(huì)在question_text字段內(nèi)進(jìn)行搜索。只要你愿意,你可以使用任意多個(gè)搜索字段,Django在后臺(tái)使用的都是SQL查詢語句的LIKE語法,但是有限制的搜索字段有助于后臺(tái)的數(shù)據(jù)庫(kù)查詢效率。

      image.png-28.2kB

      其實(shí),這個(gè)頁面還提供分頁功能,默認(rèn)每頁顯示100條,只是我們的實(shí)例只有一個(gè),囧,所以看到分頁鏈接。

      四、定制admin整體界面

      很明顯,在每一個(gè)項(xiàng)目的admin頁面頂端都顯示Django administration是很可笑的,它僅僅是個(gè)占位文本。利用Django的模板系統(tǒng),我們可以快速修改它。

      image.png-35.1kB

      1.定制項(xiàng)目模板

      manage.py文件同級(jí)下創(chuàng)建一個(gè)templates目錄。然后,打開設(shè)置文件mysite/settings.py,在TEMPLATES條目中添加一個(gè)DIRS選項(xiàng):

      # mysite/settings.py
      TEMPLATES = [
          {
              'BACKEND': 'django.template.backends.django.DjangoTemplates',
              'DIRS': [os.path.join(BASE_DIR, 'templates')],  # 要有這一行,如果已經(jīng)存在請(qǐng)保持原樣
              '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è)文件系統(tǒng)目錄的列表,是模板的搜索路徑。當(dāng)加載Django模板時(shí),會(huì)在DIRS中進(jìn)行查找。

      PS:模板的組織方式

      就像靜態(tài)文件一樣,我們可以把所有的模板都放在一起,形成一個(gè)大大的模板文件夾,并且工作正常。但是請(qǐng)一定不要這么做!強(qiáng)烈建議每一個(gè)模板都應(yīng)該存放在它所屬應(yīng)用的模板目錄內(nèi)(例如polls/templates)而不是整個(gè)項(xiàng)目的模板目錄(templates),因?yàn)檫@樣每個(gè)應(yīng)用才可以被方便和正確的重用。只有對(duì)整個(gè)項(xiàng)目有作用的模板文件才放在根目錄的templates中,比如admin界面。

      回到剛才創(chuàng)建的templates目錄中,再創(chuàng)建一個(gè)admin目錄,將admin/base_site.html模板文件拷貝到該目錄內(nèi)。這個(gè)HTML文件來自Django源碼,它位于django/contrib/admin/templates目錄內(nèi)。
      (在我的windows系統(tǒng)中,它位于C:\Python36\Lib\site-packages\django\contrib\admin\templates\admin,請(qǐng)大家參考。)

      Django的源代碼在哪里?

      如果你無法找到Django源代碼文件的存放位置,可以使用下面的命令:

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

      編輯base_site.html文件,用你喜歡的站點(diǎn)名字替換掉{{ site_header|default:_(’Django administration’) }}(包括兩個(gè)大括號(hào)一起替換掉),看起來像下面這樣:

      {% extends "admin/base.html" %}
      
      {% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
      
      {% block branding %}
      <h1 id="site-name"><a href="{% url 'admin:index' %}">投票站點(diǎn)管理界面</a></h1>
      {% endblock %}
      
      {% block nav-global %}{% endblock %}

      在這里,我們使用的是硬編碼,強(qiáng)行改名為"投票站點(diǎn)管理界面"。但是在實(shí)際的項(xiàng)目中,你可以使用django.contrib.admin.AdminSite.site_header屬性,方便的對(duì)這個(gè)頁面title進(jìn)行自定義。

      修改完后,刷新頁面,效果如下:

      image.png-34.7kB

      提示:所有Django默認(rèn)的admin模板都可以被重寫,類似剛才重寫base_site.html模板的方法一樣,從源代碼目錄將HTML文件拷貝至你自定義的目錄內(nèi),然后修改文件。

      五、定制admin首頁

      默認(rèn)情況下,admin首頁顯示所有INSTALLED_APPS內(nèi)并在admin應(yīng)用中注冊(cè)過的app,以字母順序進(jìn)行排序。

      要定制admin首頁,你需要重寫admin/index.html模板,就像前面修改base_site.html模板的方法一樣,從源碼目錄拷貝到你指定的目錄內(nèi)。編輯該文件,你會(huì)看到文件內(nèi)使用了一個(gè)app_list模板變量。該變量包含了所有已經(jīng)安裝的Django應(yīng)用。你可以硬編碼鏈接到指定對(duì)象的admin頁面,使用任何你認(rèn)為好的方法,用于替代這個(gè)app_list。

      六、源碼對(duì)照

      至此,Django教程的入門部分已經(jīng)結(jié)束了。下面將polls/admin.py的全部代碼貼出來:

      from django.contrib import admin
      
      from .models import Choice, Question
      
      
      class ChoiceInline(admin.TabularInline):
          model = Choice
          extra = 3
      
      
      class 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)

      整個(gè)投票項(xiàng)目mysite,在Pycharm中的文件組織結(jié)構(gòu)如下圖所示,對(duì)比一下你自己的,看看是否一樣。

      image.png-52.5kB

      注意2017.png是展示用的背景圖,這個(gè)可以不一樣....

      admin后臺(tái)管理站點(diǎn)可以定制得很強(qiáng)大,比如下面是博主站點(diǎn)的評(píng)論后臺(tái),完全手工定制,非常實(shí)用!

      image.png-140.9kB

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(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)遵守用戶 評(píng)論公約

        類似文章 更多