iT邦幫忙

0

Django學習紀錄 9.後台管理系統Admin

之前有在用Django寫一些小網站,現在暑假想說再來複習一下之前買的這本書
https://ithelp.ithome.com.tw/upload/images/20190724/20118889bj9fH1vhuR.jpg
於是我就把它寫成一系列的文章,也方便查語法
而且因為這本書大概是2014年出的,如今Django也已經出到2.多版
有些內容也變得不再支援或適用,而且語法或許也改變了
所以我會以最新版的Python和Django來修正這本書的內容跟程式碼

目錄:django系列文章-Django學習紀錄

9. 後台管理系統Admin

9.1 Admin介面

9.1.1 設定settings.py

INSTALLED_APPS = [
    'django.contrib.admin', # <-確認
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'restaurants',
]

確認'django.contrib.admin'有加入
接著為了確保我們的admin使用我們自己想要的語言,記得在MIDDLEWARE中加入'django.middleware.locale.LocaleMiddleware'且須置於'django.contrib.sessions.middleware.SessionMiddleware'後

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

9.1.2 設定urls.py

from django.contrib import admin # <-確認
from django.urls import path
from restaurants.views import menu

urlpatterns = [
    path('admin/', admin.site.urls), # <-確認
    path('menu/', menu),
]

確認該有的都有加入

9.1.3 建立admin的資料表

admin身為一個app也是有自己的模型,所以也需要同步到資料庫
檢查模型

python manage.py check

建立migration檔

python manage.py makemigrations admin

如果有興趣可以看生成的資料庫語法

python manage.py sqlmigrate admin 0001

同步到資料庫

python manage.py migrate admin

9.1.4 建立superuser

若還沒有把其他資料同步,必須先

python manage.py migrate

接著

python manage.py createsuperuser

設定帳號、電子郵件、密碼
帳號創建好了後
啟動伺服器並進入127.0.0.1:8000/admin
https://ithelp.ithome.com.tw/upload/images/20190717/20118889sqYp7gbAxf.png
登入進去後
https://ithelp.ithome.com.tw/upload/images/20190717/20118889K4tIRhMfHk.png
之所以沒看到我們的餐廳和食物模型
是因為還沒註冊

9.1.5 註冊模型

restaurants/admin.py

from django.contrib import admin
from restaurants.models import Restaurant, Food

admin.site.register(Restaurant)
admin.site.register(Food)

重新進入就會看到了
https://ithelp.ithome.com.tw/upload/images/20190717/20118889mufYyEG4sZ.png

9.1.6 模型欄位

class Restaurant(models.Model):
    name = models.CharField(max_length=20)
    phone_number = models.CharField(max_length=15)
    address = models.CharField(max_length=50, blank=True)

裡頭,blank=True,允許該欄位為空白,我們會在admin的頁面中發現
Address這個欄位名稱並非粗體(其他兩個欄位都是粗體),所以在新增或編輯資料時,留空不會導致錯誤
這邊要稍微深入探討一下留空的概念,在資料庫中,有兩種值都可能被稱為空白,一種是NULL,表示了空、無或是未知的、不合法的,另外一種是空字串,就像python中的None與空字串
有的時候這種差異和不一致會造成麻煩,舉例來說,我想找出所有有空白欄位的資料,我們對於使用NULL來檢查或是空字串來檢查可能會有疑義
為了統一,Django在模型生成的時候會自動將各欄位設置為非NULL:NOT NULL

CREATE TABLE "restaurants_restaurant" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(20) NOT NULL,
    "phone_number" varchar(15) NOT NULL,
    "address" varchar(50) NOT NULL
);

如此對於留白的欄位,我們便知道Django會寫入空字串到資料庫中,而不會是NULL了
但是這又產生了另外一個問題,日期跟時間的欄位是不允許空字串輸入的,為了留空,必須允許NULL值的填入,解決的辦法是在模型撰寫時,用參數null=True來允許表格為NULL,結合以上兩點,對於一個可允許留空的時間日期欄位,我們必須同時指定blank=True和null=True

date = models.DateField(blank=True, null=True)

而且Django會用以下規則為模型在admin中的欄位名稱命名
欄位名稱 = 屬性名稱首字大寫 + 以空白取代屬性中的底線
例如: phone_number變為Phone number
如果不滿意命名規則想要改變
可以這樣做

phone_number = models.CharField(max_length=15,verbose_name='foneNum')

9.2 admin管理功能與自定義ModelAdmin類別

9.2.1 列表顯示

django admin預設只能看到模型的第一個屬性
https://ithelp.ithome.com.tw/upload/images/20190717/20118889YAmpyldpJ0.png
如果想要能夠一次顯示所有屬性
admin.py

from django.contrib import admin
from restaurants.models import Restaurant, Food

class RestaurantAdmin(admin.ModelAdmin):
    list_display = ('name', 'phone_number', 'address')

admin.site.register(Restaurant, RestaurantAdmin)
admin.site.register(Food)

結果:
https://ithelp.ithome.com.tw/upload/images/20190717/20118889p69R7J8Pcg.png

9.2.2 列表過濾

可以放入列表過濾的資料欄位有
BooleanField
CharField
DateField
DateTimeField
IntegerField
ForeignKey
ManyToManyField
範例:
admin.py

from django.contrib import admin
from restaurants.models import Restaurant, Food


class RestaurantAdmin(admin.ModelAdmin):
    list_display = ('name', 'phone_number', 'address')


class FoodAdmin(admin.ModelAdmin):
    list_display = ('name', 'restaurant', 'price')
    list_filter = ('is_spicy',)


admin.site.register(Restaurant, RestaurantAdmin)
admin.site.register(Food, FoodAdmin)

結果
https://ithelp.ithome.com.tw/upload/images/20190717/20118889qYk7tuKJ6m.png

9.2.3 搜尋欄位

class RestaurantAdmin(admin.ModelAdmin):
    list_display = ('name', 'phone_number', 'address')
    search_fields = ('name',)

https://ithelp.ithome.com.tw/upload/images/20190717/201188890ClfhQFQxU.png
就會看到多出一個以name為主的搜尋欄位
使用者也可設置多個可被搜尋的欄位

9.2.4 排序

class FoodAdmin(admin.ModelAdmin):
    list_display = ('name', 'restaurant', 'price')
    list_filter = ('is_spicy',)
    ordering = ('-price')

9.2.5 自定義編輯欄位

class FoodAdmin(admin.ModelAdmin):
    list_display = ('name', 'restaurant', 'price')
    list_filter = ('is_spicy',)
    fields = ('price', 'restaurant')
    ordering = ('-price',)

這樣就可以設定哪些欄位會出現在admin頁面中,沒有出現在頁面中就不能被手動編輯
https://ithelp.ithome.com.tw/upload/images/20190717/20118889fAfJWXLuTB.png

上一篇:Django學習紀錄 8.模型與資料庫

下一篇:Django學習紀錄 10.使用者互動與表單


尚未有邦友留言

立即登入留言