Django基础(21): Django admin管理后台详解(下)如何自定义actions, 表单和美化admin

本文是Django Admin详解系列文章的最后一篇,将重点介绍如何自定义动作(action), 如何自定义表单字段(form fields)和美化Django admin。如果你还没有阅读过前面两篇文章,建议先阅读。

  • Django基础(19): Django Admin管理后台详解(上)

  • Django基础(20): Django admin管理后台详解(中)如何自定义list_display和list_filter

Django基础(21): Django admin管理后台详解(下)如何自定义actions, 表单和美化admin_第1张图片

 

谓action及如何自定义action

action即动作,是你对一个选定查询集(queryset)要进行的操作。当你选定一个查询集(queryset)后,你可以点击action下拉菜单选择action,然后点击Go对其进行批量操作(如下所示)。Django admin默认的action只有删除(delete)。

Django基础(21): Django admin管理后台详解(下)如何自定义actions, 表单和美化admin_第2张图片

现在如果你要将文章由草案(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下面多了一个"发布所选文章的"选项了。

Django基础(21): Django admin管理后台详解(下)如何自定义actions, 表单和美化admin_第3张图片

本例中使用了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

你可能感兴趣的:(Django)