Django管理员操作:仅用一种方法为所有选择生成操作

时间:2018-09-27 12:30:16

标签: python django

对于如下所示的模型:

class MyModel(models.Model):
    my_field = models.CharField(choices=FIELD_CHOICES)

其中

FIELD_CHOICES = [("Update this", "Update this"),
                 ("Update that", "Update that"), 
                 ("Update something else", "Update something else"), ]

并具有以下管理员视图

class MyModelAdmin(admin.ModelAdmin):
    list_display = ["user", ]

如果我们想采取行动来使用其任何值更新字段,则可以为ModelAdminView中的每个值添加一个方法,如下所示:

    actions = ("update_this", "update_that", "update_something_else")

    def update_this(self, request, queryset):
        queryset.update(my_field="Update this")

    def update_that(self, request, queryset):
        queryset.update(my_field="Update that")

    def update_something_else(self, request, queryset):
        queryset.update(my_field="Update something else")

但是,除了可以从字段的选择中检索的某些部分之外,所有这些方法都是相同的...

Django仅使用一种通用方法提供任何方式为字段的所有选择生成操作吗?

1 个答案:

答案 0 :(得分:1)

您绝对可以使用Django管理员执行此类操作。我通常通过子类化Django ModelAdmin类的get_actions方法来实现。这是一个可能与您想要的完全不同的示例,但至少应说明一种动态创建任意数量的基本执行相同操作的批量操作的方法:

from django.contrib import admin

class MyModelAdmin(admin.ModelAdmin):

    _update_fields = (
        # ('Text for the dropdown', 'a_unique_function_name', 'some value')
        ('This', 'function_name_for_this', 'this value'),
        ('That', 'function_name_for_that', 'that value'),
        ('Other Thing', 'function_name_for_other_thing', 'some other value'),
    )

    def get_actions(self, request):
        def func_maker(value):
            # this function will be your update function, just mimic the traditional bulk update function
            def update_func(self, request, queryset):
                queryset.update(my_field=value)
            return update_func

        # check out django.contrib.admin.options.ModelAdmin.get_actions for more details - basically it
        # just returns an ordered dict, keyed by your action name, with a tuple of the function, a name,
        # and a description for the dropdown.
        # Python 2.7-style:
        actions = super(MyModelAdmin, self).get_actions(request)
        # If using Python 3, call it like so:
        # actions = super().get_actions(request)

        # You can just tack your own values/actions onto it like so:
        for description, function_name, value in self._update_fields:
            func = func_maker(value)
            name = 'update_{}'.format(function_name)
            actions['update_{}'.format(function_name)] = (func, name, 'Update {}'.format(description))

        return actions