不得不說,Django的Admin真的給開發帶來很多便利,這不,我又來折騰了,這次是新增自定義的action
這個自定義的Action可以看看官方文件的介紹,很詳細,不再贅述。
https://docs.djangoproject.com/en/3.0/ref/contrib/admin/actions/
介面效果
Django預設的新增完action是要選擇下面的物件才能提交的,不過我不需要啊,我就要簡簡單單點選開始抽獎就直接抽獎出來了,功夫不負有心人,我還是在Stack Overflow找到了解決方案,(果然是面向sof程式設計)
接下來介紹一下如何實現的~
定義Action
在admin.py
中寫程式碼:
@admin.register(models.PrizeLog)
class PrizeLogAdmin(admin.ModelAdmin):
actions = ['draw_prize']
def draw_prize(self, request, queryset):
pass
draw_prize.short_description = '開始抽獎'
draw_prize.type = 'warning'
draw_prize.confirm = '確認即開始抽獎併傳送中獎通知~'
這樣就把按鈕顯示出來了,但是現在點選完是不會執行draw_prize
方法裡面的程式碼的,因為Django限制必須選擇至少一個物件才能進行action。
接下來我們曲線救國,來繞過這個限制。
移除限制
還是在這個Admin類中,編寫程式碼:
@admin.register(models.PrizeJoinLog)
class PrizeJoinLogAdmin(admin.ModelAdmin):
actions = ['draw_prize']
def changelist_view(self, request, extra_context=None):
try:
action = self.get_actions(request)[request.POST['action']][0]
action_acts_on_all = action.acts_on_all
except (KeyError, AttributeError):
action_acts_on_all = False
if action_acts_on_all:
post = request.POST.copy()
post.setlist(admin.helpers.ACTION_CHECKBOX_NAME,
self.model.objects.values_list('id', flat=True))
request.POST = post
return super(PrizeJoinLogAdmin, self).changelist_view(request, extra_context)
def draw_prize(self, request, queryset):
pass
draw_prize.short_description = '開始抽獎'
draw_prize.type = 'warning'
draw_prize.confirm = '確認即開始抽獎併傳送中獎通知~'
draw_prize.acts_on_all = True
注意上述程式碼,我們新增了changelist_view
這個方法,並且最後一行給draw_prize
加了個屬性acts_on_all
並賦值為True
(無敵動態語言Python瞭解一下)
這樣在提交的時候,changelist_view
檢查到action有個acts_on_all
屬性,就會自動帶上所有物件,相當於自動幫我們勾選了全部物件的意思。妙啊~
歡迎交流
不過這種方式感覺也不是很完美,如果大佬們有什麼更好的解決方法,歡迎留言討論~