之前有在用Django寫一些小網站,現在暑假想說再來複習一下之前買的這本書
於是我就把它寫成一系列的文章,也方便查語法
而且因為這本書大概是2014年出的,如今Django也已經出到2.多版
有些內容也變得不再支援或適用,而且語法或許也改變了
所以我會以最新版的Python和Django來修正這本書的內容跟程式碼
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',
]
from django.contrib import admin # <-確認
from django.urls import path
from restaurants.views import menu
urlpatterns = [
path('admin/', admin.site.urls), # <-確認
path('menu/', menu),
]
確認該有的都有加入
admin身為一個app也是有自己的模型,所以也需要同步到資料庫
檢查模型
python manage.py check
建立migration檔
python manage.py makemigrations admin
如果有興趣可以看生成的資料庫語法
python manage.py sqlmigrate admin 0001
同步到資料庫
python manage.py migrate admin
若還沒有把其他資料同步,必須先
python manage.py migrate
接著
python manage.py createsuperuser
設定帳號、電子郵件、密碼
帳號創建好了後
啟動伺服器並進入127.0.0.1:8000/admin
登入進去後
之所以沒看到我們的餐廳和食物模型
是因為還沒註冊
restaurants/admin.py
from django.contrib import admin
from restaurants.models import Restaurant, Food
admin.site.register(Restaurant)
admin.site.register(Food)
重新進入就會看到了
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')
django admin預設只能看到模型的第一個屬性
如果想要能夠一次顯示所有屬性
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)
結果:
可以放入列表過濾的資料欄位有
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)
結果
class RestaurantAdmin(admin.ModelAdmin):
list_display = ('name', 'phone_number', 'address')
search_fields = ('name',)
就會看到多出一個以name為主的搜尋欄位
使用者也可設置多個可被搜尋的欄位
class FoodAdmin(admin.ModelAdmin):
list_display = ('name', 'restaurant', 'price')
list_filter = ('is_spicy',)
ordering = ('-price')
class FoodAdmin(admin.ModelAdmin):
list_display = ('name', 'restaurant', 'price')
list_filter = ('is_spicy',)
fields = ('price', 'restaurant')
ordering = ('-price',)
這樣就可以設定哪些欄位會出現在admin頁面中,沒有出現在頁面中就不能被手動編輯