Django基礎(21): Django admin管理後臺詳解(下)如何自定義actions, 表單和美化admin
本文是Django Admin詳解系列文章的最後一篇,將重點介紹如何自定義動作(action), 如何自定義表單欄位(form fields)和美化Django admin。如果你還沒有閱讀過前面兩篇文章,建議先閱讀。
謂action及如何自定義action
action即動作,是你對一個選定查詢集(queryset)要進行的操作。當你選定一個查詢集(queryset)後,你可以點選action下拉選單選擇action,然後點選Go對其進行批量操作(如下所示)。Django admin預設的action只有刪除(delete)。
現在如果你要將文章由草案(draft)狀態變為發表(published)狀態,你只能一個一個地修改, 很麻煩。現在我們可以自定義一個action,實現文章狀態的批量修改。程式碼如下所示:
#blog/admin.py
class ArticleAdmin(admin.ModelAdmin): '''設定列表可顯示的欄位''' list_display = ('title', 'author', 'status', 'mod_date', 'show_tags') '''自定義actions''' actions = ['make_published'] def make_published(self, request, queryset): queryset.update(status='p') make_published.short_description = "釋出所選文章"
我們自定義了一個名為make_published的方法,並將其加入到了ArticleAdmin的actions屬性(別忘了加引號哦)。我們還給該方法添加了一個簡單描述(short_description)。現在如果你重新整理頁面,你就可以看到action下面多了一個"釋出所選文章的"選項了。
本例中使用了queryset.update方法實現了資料批量更新, 提升了工作效率。如果你想對queryset中的物件一個一個修改或匯出,你應該怎麼辦呢? 此時你可以遍歷queryset,對單個obj逐一處理, 如下所示:
def action_func(self, request, queryset): for obj in queryset: do_something(obj)
action的許可權管理
一個網站可能有多個人員有許可權登入管理後臺,如果每個人都有delete或匯出資料的許可權,是件挺可怕的事情。萬一哪天某人對公司不滿意清空資料或匯出所有客戶資料跑路呢? 所以我們必需對action也設定一定的許可權。實現這個只需定義allowed_permissions屬性即可。下例中要求只有change許可權的管理人員才能更改文章發表狀態。
make_published.allowed_permissions = ('change',)
下例中我們重寫了get_actions方法,只給了使用者名稱為John批量刪除物件的許可權。如果使用者名稱不為John,我們把delete_selected動作從下拉選單中刪除。
class ArticleAdmin(admin.ModelAdmin): def get_actions(self, request): actions = super().get_actions(request) if request.use.username != 'John': if 'delete_selected' in actions: del actions['delete_selected'] return actions
自定義顯示錶單
如果我們想實現根據不同的使用者顯示不同表單form,我們可以通過重寫get_form方法實現。如下例中給Superuser顯示了不同的表單。
class MyModelAdmin(admin.ModelAdmin): def get_form(self, request, obj=None, **kwargs): if request.user.is_superuser: kwargs['form'] = MySuperuserForm return super().get_form(request, obj, **kwargs)
自定義顯示錶單的ForeinKey欄位
django admin對於一個欄位預設會顯示所有的ForeignKey(比如文章類別)。下利中通過重寫formfiled_for_foreignkey方法可只顯示使用者自己建立的文章類別。
class MyModelAdmin(admin.ModelAdmin): def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == "cateogry": kwargs["queryset"] = Category.objects.filter(owner=request.user) return super().formfield_for_foreignkey(db_field, request, **kwargs)
自定義顯示錶單的多對多欄位
通過重寫formfiled_for_manytomany方法可只顯示使用者自己建立的多對多欄位。
class MyModelAdmin(admin.ModelAdmin): def formfield_for_manytomany(self, db_field, request, **kwargs): if db_field.name == "cars": kwargs["queryset"] = Car.objects.filter(owner=request.user) return super().formfield_for_manytomany(db_field, request, **kwargs)
自定義顯示錶單的Choice欄位
下例中通過重寫formfiled_for_choice_field方法給superuser多了一個選擇。
class MyModelAdmin(admin.ModelAdmin): def formfield_for_choice_field(self, db_field, request, **kwargs): if db_field.name == "status": kwargs['choices'] = ( ('accepted', 'Accepted'), ('denied', 'Denied'), ) if request.user.is_superuser: kwargs['choices'] += (('ready', 'Ready for deployment'),) return super().formfield_for_choice_field(db_field, request, **kwargs)
自定義搜尋選項search_field
如果你定義了搜尋選項search_field, django admin上就會出現一個搜尋框,允許你按定義的欄位快速搜尋一個物件。注意search_field只能用於CharField或TextField。
search_fields = ['title', 'user__email'] # 按文章title和使用者email搜尋 search_fields = ['user__first_name'] # 按使用者first name模糊查詢icontains search_fields = ['user__first_name__iexact'] # 按使用者first name精確匹配
如何美化Django的admin
如果你不使用第三方的庫如django-xadmin, 你唯一能夠美化django admin的方法就是覆蓋它本來的模板。預設的django模板是放在contrib/admin/templates/admin目錄下的。django的模板美化可以針對某個專案(project), 某個應用(app)或某個模型(model)來進行,提供了非常大的靈活度。
1. 針對專案(project)全站美化。
按如下順序新建目錄,拷入新的模板修改即可。
my_project/templates/admin/
2. 針對應用(app)美化。
按如下順序新建目錄,拷入新的模板修改即可。
my_project/templates/admin/my_app
2. 針對模型(model)美化。
按如下順序新建目錄,放入新的模板即可。
my_project/templates/admin/my_app/model_name
小結
本文總結了如何自定義action並對action設定許可權,還詳細分析瞭如何自定義顯示錶單及美化django admin。接下來我們繼續會用Django開發些有趣的專案,歡迎關注。
非廣告: 今天雙11,阿里雲百度雲騰訊雲都在打折,建議大家去申請個1核2G的雲伺服器(centos或ubuntu版的)學習練手,才100-200元/年,非常值得投入。小編我後續講解django專案部署時會用到。
大江狗
2018.11.11