1. 程式人生 > Django入門教學 >21 Django 自帶的 Admin 管理工具

21 Django 自帶的 Admin 管理工具

Django 給我們提供了一個內建的完整功能的管理頁面。在這個管理頁面,我們可以對實現的模型物件進行完整的增刪改查操作,足以滿足我們的日常需求,接下來開始進入這個管理工具的使用。

1. 初識 Admin Web

首先 Django 工程中預設自帶 Admin 管理工具並作為內建應用在 settings.py 中的 INSTALLED_APPS 上進行了註冊:

INSTALLED_APPS = [
    # 註冊 admin 應用
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes'
, 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # 註冊應用 'hello_app' ]

接下來為了能訪問到這個後臺管理的 Web 頁面,Django 在初始化專案時,自動為我們添加了這個 Web 頁面的相關的路由資訊:

# first_django_app/urls.py

urlpatterns = [
    # admin後臺管理頁面的地址
    url('admin/', admin.site.urls),
]

注意:如果不想要這個自帶的後臺管理系統,也可以直接刪除這個 URLconf 配置即可。

我們啟動測試的 Django 工程,然後手動訪問這個 admin 後臺,具體操作如下:

(django-manual) [root@server first_django_app]# python manage.py runserver 0.0.0.0:8888
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

April 12, 2020 - 15:11:39
Django version 2.2.11, using settings 'first_django_app.settings'
Starting development server at http://0.0.0.0:8888/
Quit the server with CONTROL-C.

注意:對於上面出現的告警資訊是因為我們沒有做資料庫的遷移。在 Django 中為我們設計了一些內部的表,比如用來儲存 admin 管理工具賬號的表,比如儲存 session 的表等。只需要使用 Django 提供的 makemigrationsmigrate 命令即可:

(django-manual) [root@server first_django_app]# python manage.py makemigrations
Migrations for 'hello_app':
  hello_app/migrations/0002_auto_20200412_1512.py
    - Alter field vip_level on member
(django-manual) [root@server first_django_app]# python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, hello_app, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying hello_app.0002_auto_20200412_1512... OK
  Applying sessions.0001_initial... OK

可以通過 Navicate 工具檢視到 Django 給我們生成了 10 張表內部表,這 10 張表之間存在許多關聯的地方。如下圖所示:

圖片描述

再次使用 runserver 命令啟動 Django 工程時,就不會再有遷移相關的告警提示了。這個時候我們訪問 admin/ 地址,就可以看到如下的登入頁面。

圖片描述

這裡的登入賬號和密碼我們可以通過 Django 提供的 createsuperuser 命令完成:

(django-manual) [root@server first_django_app]# python manage.py createsuperuser
Username (leave blank to use 'root'): admin
Email address: [email protected]
Password: 
Password (again): 
Superuser created successfully.

上面命令執行成功後,我們可以看到資料庫的 auth_user 表中多出了一條使用者資訊的記錄,正是我們上面設定的使用者名稱和密碼資訊。

圖片描述

使用這個剛建立的使用者名稱和密碼登入進入管理系統頁面如下:

圖片描述

在首頁中,我們可以對使用者和使用者組進行管理,包括對錶中資料的更新、修改和刪除。如下是新增使用者以及新增完成後的操作示例。完成新增完成後,還可以選擇該條記錄進行調整,直接影響的就是資料庫中的 auth_user 表。

圖片描述

圖片描述
除了管理內建的表外,Django 的 admin 功能還可以管理我們定義的模型表,實現基本的增刪改查操作。我們繼續用前面的會員表和會員等級表進行實操。

hello_app/admin.py 檔案中新增如下程式碼,將我們定義的模型註冊到 admin 模組中:

from django.contrib import admin
from .models import Member, VIPLevel

# Register your models here.
admin.site.register([Member, VIPLevel])

重啟 Django 工程,然後繼續訪問 admin 管理頁面,讓我們可以看到我們定義的模型出現在了管理頁面上。而且我們還可以操作我們的模型,進行增刪改查資料。

圖片描述

注意:這裡表中資料的展示方式是按照模型類中定義的 __str__ 魔法函式決定的。

圖片描述

圖片描述

這裡可以看到 Member 表的關聯表中資料,使用起來非常方便。

2. 深入 Admin Web

2.1 自定義模型管理頁面

我們可以看到,預設 Admin 管理頁面給我們提供的增刪改查操作,頁面的內容比較單一。如果我們想自定義管理頁面的內容以及功能的時候,可以使用 ModelAdmin 類,它是模型在 Admin 介面中的表示形式,封裝了模型的 Admin 功能和選項。通常,會將它們放在應用中的名為 admin.py 的檔案裡。

from django.contrib import admin
from .models import Member, VIPLevel

@admin.register(Member)
class MemberAdmin(admin.ModelAdmin):
    pass

@admin.register(VIPLevel)
class VIPLevelAdmin(admin.ModelAdmin):
    pass

上面這樣的寫法等價於我們使用預設的管理方式,和之前的 admin.site.register([Member, VIPLevel]) 註冊函式功能一致,僅僅是表示註冊。我們來看看 ModelAdmin 的常用屬性值:

  • actions_on_top / actions_on_bottom:用來控制列表頁按鈕顯示位置;
  • date_hierarchy:只可作用在 DateField 和 DateTimeField 上。設定後, 可以根據時間段, 去過濾資料;
  • empty_value_display:此屬性會覆蓋記錄欄位為空的預設顯示值。 預設值為-(破折號);
  • exclude:排除新增/編輯頁面需要顯示的欄位;
  • fields:指定新增、編輯頁面要顯示的欄位;
  • fieldsets:設定 fieldsets 以控制管理頁面的 “Add” 和 “Change” 按鈕跳轉頁面的佈局;
  • list_display:控制列表頁要顯示的欄位;如果我們沒有設定 list_display 屬性,那麼 admin 站點僅顯示一列,顯示 __str__() 的結果,這正是我們前面看到的現象;
  • list_display_links:指定哪些在列表頁顯示的欄位上加連結;
  • list_editable:指定哪些欄位可以直接在列表頁編輯;
  • list_filter:指定列表頁過濾欄位;
  • list_per_page:指定列表頁每頁顯示的記錄數;
  • ordering:指定欄位的排序,比如正序、倒敘等等。

我們使用 ModelAdmin 類來改造下前面的 Member 模型的展示頁面,程式碼如下:

from django.contrib import admin
from .models import Member, VIPLevel

# Register your models here.

@admin.register(Member)
class MemberAdmin(admin.ModelAdmin):
    actions_on_top = False
    actions_on_bottom = True
    date_hierarchy = 'register_date'
    empty_value_display = '-empty-'
    list_display = ('name', 'age', 'city', 'sex', 'occupation', 'phone_num')
    list_editable = ('age', 'sex')
    list_filter = ('occupation', 'city')
    ordering = ['-age']
    list_per_page = 5

@admin.register(VIPLevel)
class VIPLevelAdmin(admin.ModelAdmin):
    pass

每個屬性值對應的效果如下圖所示:

圖片描述

更多關於 ModelAdmin 類的屬性及其用法,我們需要參看官方文件,那裡有十分詳細的屬性說明以及程式碼演示。及時檢視官方文件輔助學習 Django 是一個非常有效的學習手段,畢竟那裡才是 Django 一切學習文件的來源地。

2.2 Admin 中的 actions

我們前面看到,Admin 中的 actions 是控制模型列表的動作,比如頁面上批量更新操作等。來看如下的示例程式碼:

from django.contrib import admin
from .models import Member, VIPLevel

# Register your models here.
def make_men(modeladmin, request, queryset):
    queryset.update(sex=0)
make_men.short_description = "全部轉成男性"

@admin.register(Member)
class MemberAdmin(admin.ModelAdmin):
    actions_on_top = False
    actions_on_bottom = True
    date_hierarchy = 'register_date'
    empty_value_display = '-empty-'
    list_display = ('name', 'age', 'city', 'sex', 'occupation', 'phone_num')
    list_editable = ('age', 'sex')
    list_filter = ('occupation', 'city')
    ordering = ['-age']
    list_per_page = 5
    actions = [make_men]

@admin.register(VIPLevel)
class VIPLevelAdmin(admin.ModelAdmin):
    pass

我們自定義了一個 make_men() 方法,這個方法會作為 MemberAdmin 物件的一個 action 方法。然後給該方法新增 short_description 屬性,最後將該方法新增到 ModelAdmin 物件的 actions 屬性中去。這樣在模型管理頁面的 Action 欄會出現對應的標籤,用於實現相應的動作,如下圖所示:

圖片描述

該 action 方法固定有三個引數:

  • 當前的 ModelAdmin 物件例項;
  • 一個 HttpRequest 例項,用於表示當前的 HTTP 請求;
  • 使用者選中記錄對應組成的 QuerySet 例項;

選擇我們定義的 action 方法,然後點選 Go 按鈕,就可以將所有選中記錄的性別改為男性。操作結果如下:

圖片描述

我們可以看到每個模型管理頁面的 Action 欄的下拉框都會有一個預設的動作,就是刪除選中的記錄。如果我們不想要這個動作選項,可以在 admin.py 中加上admin.site.disable_action 程式碼即可。如果有的模型想要有這個選項,而另一個模型不想要這個選項,則可以使用如下的方式完成需求:

# 關閉本應用模型的刪除選中動作選項
admin.site.disable_action('delete_selected')

# Member模型管理頁面不會有刪除選中動作選項
@admin.register(Member)
class MemberAdmin(admin.ModelAdmin):
    ...

# VIPLevel模型管理頁面則會有刪除選中動作選項
class VIPLevelAdmin(admin.ModelAdmin):
    actions = ['delete_selected', 'a_third_action']
    ...

圖片描述

最後,如果直接不想要這個 Action 欄,我們直接給模型對應的 ModelAdmin 物件設定 action = None 即可,結果如下:

圖片描述

3. 小結

這裡我們簡單的介紹了下 Django 自帶的 Admin 管理頁面,同時通過配置一行程式碼可以管理我們定義的模型。此外,為了能夠自定義管理頁面的內容以及相關的功能,學習了 Django 提供的 ModelAdmin 類並進行了實操演示。不過,儘管 Django 為我們提供了這麼多功能,在大多數場景下還是顯得非常簡陋和不友好,還需要引入第三方的外掛來豐富和美化我們的後臺管理功能。在後面的第三方模組小節中我們會介紹一個第三方的 Django 後臺管理系統—xadmin,然後會在該管理系統的基礎上進行實戰開發。