今天我們繼續來討論,究竟 Models 與 Admin之間還藏著什麼不可告人的秘密
繼 Day10所提到的,Django 在創建資料庫的時候,實際上背後偷偷地增加的 key = id 的欄位,為了顯示這個id,我們必須創造一個 models 類別的管理者,必須將管理者一併登入進 Admin.py 才行
而你好不容易在 models.py 新增的 VendorAdmin,之後還要去 admin.py 登陸,你可能會覺得有點麻煩,有沒有更方便的做法? 答案是有的! 而且還能一併將原本登入進去的 Vendor 拿掉
方法就是在 VendorAdmin 上方加上 decorator@admin.register(classname)
@admin.register(Vendor)
class VendorAdmin(admin.ModelAdmin):
# 這裡我一併將 Vendor 類別 其它的欄位都加進來了
list_display = ['id', 'vendor_name', 'store_name', 'phone_number', 'address']
不要忘記去 admin.py 將 Vendor 註解掉唷!
from django.contrib import admin
from .models import Vendor, Food, VendorAdmin
# Register your models here.
# admin.site.register(Vendor) # < 註解
admin.site.register(Food)
完成上述兩事情,再下 python manage.py runserver
,它能正常的運作,這方法是不是相對簡單很多 ^ ^
Python 的 decorator是一個蠻tricky的方法,不過了解操作手法之後,你會發現它的強大! 這裡不說明它的功能,不過推薦一個猴子都看得懂的英文教學 Primer on Python Decorators
同一個管理者可以登入多個類別,但是list_display的設定必須兩個類別都有相同的欄位,因此這裡我們不建議這麼做
上面我們試著將每一個欄位都SHOW出來了,但此刻你不知道是不是也會想 : 如果我的欄位不只這幾個,那一個個填鴨上去,那真的很無聊! 但其實我們可以更聰明的讓Python幫我們填
修改 list_display = field.name for field in Vendor._meta.fields
@admin.register(Vendor)
class VendorAdmin(admin.ModelAdmin):
list_display = [field.name for field in Vendor._meta.fields]
# 上下兩者目的相同
# list_display = ['id', 'vendor_name', 'store_name', 'phone_number', 'address']
此時我們將 Food 也一併透過相同的方式登陸進來
@admin.register(Food)
class FoodAdmin(admin.ModelAdmin):
list_display = [field.name for field in Food._meta.fields]
並使用Food的資料來做說明,我預先加入了另外兩筆資料進來
當資料庫一大的時候,很多資料常常不是我們想要看的,我們可能只想看某一類的資料,像是只想搜尋某種價位的食物,那麼你就需要用到 過濾 list_filter,在Food裡面新增 list_filter,並將要過濾的欄位填入list_filter = ('price_name',)
@admin.register(Food)
class FoodAdmin(admin.ModelAdmin):
list_display = [field.name for field in Food._meta.fields]
# 過濾 price_name
list_filter = ('price_name',)
我現在才意識我取了一個爛名字,到底什麼是price_name xD,應該是 food_price,anyway,大家了解就好
新增完便能夠看到右方多了一個過濾的欄位,此時你便能透過 food_price price_name 進行過濾的動作
這只是一個簡單的過濾,有時候你想做的不只是這樣子,因為10號剛領薪,你想要犒賞自己,只想要找 >50價位的麵包,但是資料庫顯示的資料可能有 60 65 70... 各種價位的麵包,這時候你便可以自行設定
# 額外 import 這個套件
from django.utils.translation import gettext_lazy as _
# 自行宣告 類別
class Morethanfifty(admin.SimpleListFilter):
title = _('price')
parameter_name = 'compareprice' # url最先要接的參數
def lookups(self, request, model_admin):
return (
('>50',_('>50')), # 前方對應下方'>50'(也就是url的request),第二個對應到admin顯示的文字
('<=50',_('<=50')),
)
# 定義查詢時的過濾條件
def queryset(self, request, queryset):
if self.value() == '>50':
return queryset.filter(price_name__gt=50)
if self.value() == '<=50':
return queryset.filter(price_name__lte=50)
@admin.register(Food)
class FoodAdmin(admin.ModelAdmin):
list_display = [field.name for field in Food._meta.fields]
# 將 Morethanfifty 填入
list_filter = (Morethanfifty,)
我們選擇了 >50 的選項,此時只會顯示>50的食物,我們就能夠好好犒賞一下自己了 ^^
選擇了 >50 會顯示的 url為 http://127.0.0.1:8000/admin/vendor/food/?compareprice=>50
前方的 compareprice 就是對應到我上面所說的 parameter_name,而 >50 則是我們定義的其中一個選項
是不是很簡單(X
除了使用Django內建的 list_filter,你也可以自行設定區間範圍
今天差不多就先講到這裡,自定義過濾的部分若是有不懂的地方也歡迎留言,不過我相信大家應該都沒麼問題
model 跟 admin 實在有太多東西可以玩拉 (哈哈