Django 进阶学习 - 动态actions

Django 进阶学习 - 动态actions

Posted May 03, 2016

Django后台默认只有一个动作Delete selected xxxxs, 那么如果自定义动作该怎么办, 也很容易, 直接写个类似于这种的函数

Python

def make_published(modeladmin, request, queryset):
    queryset.update(status='p')

然后绑定到ModelAdmin的actions属性

admin.py

Python

class TriggerAdmin(admin.ModelAdmin):
    empty_value_display = u'无规则'
    list_display = ('__str__', 'id')
    search_fields = ('description',)
    list_filter = (IpFilter, 't_type')
    actions = (make_published,) #指定自定义actions

action在程序启动后就会正常工作, 现在我有个项目需要根据一张表(role表)来动态扩展动作, 所以这种方法没有办法扩展。 总不能在role表加一个数据就要重启django把? 显然不能这样做, 当然django有动态生成action的方法, 那就是admin.ModelAdminget_actions()方法

首先写个闭包

根据role生成action function

actions.py

Python

from django.utils.translation import ugettext as _, ugettext_lazy
from controller.models import SwitchRole
from controller.models import ConvergeRole

def _with_role(role, switch=True):
    """闭包实现, 设置role, switch为通用变量,  返回一个action函数"""

    # 根据role类型判断字段类型
    if isinstance(role, SwitchRole):
        field_name = "switch_role"
    elif isinstance(role, ConvergeRole):
        field_name = "converge_role"
    else:
        return None

    def set_selected(modeladmin, request, queryset):
        """
        规则动作
        """
        # 根据开关选项, 来判断字段value
        kwargs = {}
        if switch:
            field_value = role.pk
        else:
            field_value = None

        kwargs[field_name] = field_value
        return queryset.update(**kwargs)

    set_selected.short_description = ugettext_lazy(u"设置规则为: %s" % role)
    set_selected.__name__ = "set_role_%s_%s" % (field_name, role.pk)
    return set_selected

注意: set_selected.short_description为后台管理界面actions下拉菜单显示的文本, set_selected.__name__ 是函数的名称, 由于我们是多个,所以函数的名称一定要唯一.

下面重写get_actions()

admin.py

Python

class TriggerAdmin(admin.ModelAdmin):
    empty_value_display = u'无规则'
    list_display = ('__str__', 'id', 'ip', 't_type',
            'get_converge', 'get_switch', 'level')
    search_fields = ('description',)
    list_filter = (IpFilter, 't_type', 'converge_role', 'switch_role', 'level')

    def get_actions(self, request):
        # 设置Role动作
        fns = [ _with_role(i) for i in SwitchRole.objects.all() ]
        fns += [_with_role(i) for i in ConvergeRole.objects.all()]

        # 清空Role动作
        if SwitchRole.objects.all():
            role = _with_role(SwitchRole.objects.all()[0], switch=False)
            role.__name__ = 'remove_switch_role'
            role.short_description = ugettext_lazy(u"清空开关规则")
            fns.append(role)

        if ConvergeRole.objects.all():
            role = _with_role(ConvergeRole.objects.all()[0], switch=False)
            role.__name__ = 'remove_converge_role'
            role.short_description = ugettext_lazy(u"清空聚合规则")
            fns.append(role)

        actions = [ self.get_action(fn) for fn in fns ]
        actions = OrderedDict(
            (name, (func, name, desc))
            for func, name, desc in actions
        )
        return actions

这样每次刷新页面get_actions都会执行一遍, 做到动态actions.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏更流畅、简洁的软件开发方式

分页解决方案 之 数据访问函数库——另类的思路、另类的写法,造就了不一样的发展道路。

    如何访问数据库?一个老掉牙的问题,方法多了去了,什么直接使用ado.net、使用SQLHelp、使用微软的企业库、使用ORM、使用LinQ to SQL...

2438
来自专栏大内老A

ASP.NET Core中如影随形的”依赖注入”[上]: 从两个不同的ServiceProvider说起

我们一致在说 ASP.NET Core广泛地使用到了依赖注入,通过前面两个系列的介绍,相信读者朋友已经体会到了这一点。由于前面两章已经涵盖了依赖注入在管道构建过...

4097
来自专栏Petrichor的专栏

git: .gitignore文件 (忽略文件)

Note: 切记目录名后面 一定要加 反斜杠 / ,不然会当成 单文件 处理。

1352
来自专栏大内老A

.NET Core采用的全新配置系统[5]: 聊聊默认支持的各种配置源[内存变量,环境变量和命令行参数]

较之传统通过App.config和Web.config这两个XML文件承载的配置系统,.NET Core采用的这个全新的配置模型的最大一个优势就是针对多种不同配...

2029
来自专栏决胜机器学习

《Redis设计与实现》读书笔记(十一) ——Redis数据库与键空间

《Redis设计与实现》读书笔记(十一) ——Redis数据库与键空间 (原创内容,转载请注明来源,谢谢) 一、redis数据库 redis服务器将所有数据库都...

3836
来自专栏Jackson0714

干货分享:详解线程的开始和创建

2826
来自专栏跟着阿笨一起玩NET

Unit Test单元测试时如何模拟HttpContext

参考文章:http://blog.csdn.net/bclz_vs/article/details/6902638

1551
来自专栏码匠的流水账

java9系列(一)安装及jshell使用

官网地址http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-38485...

881
来自专栏GopherCoder

『简书API:Golang 处理 json 用法讲解(4):视频版』

2106
来自专栏抠抠空间

Django之views系统

Django的View(视图)简介 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。 响应可以是一张网页...

4047

扫码关注云+社区

领取腾讯云代金券