1. 程式人生 > >Django基礎(21): Django admin管理後臺詳解(下)如何自定義actions, 表單和美化admin

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