如何装饰Django中的管理操作,action .__ name__用作dict键?

时间:2016-12-19 18:20:52

标签: python django python-decorators

为了避免重复,我决定装饰我在Django管理中使用的一些操作。装饰器非常简单 - 包装函数,对其进行评估,并且在TransitionError的情况下向用户显示相应的错误消息。它也会获得short_description并应用它。

def transition_action(short_description):
    def decorator(fn):
        def wrapped(modeladmin, request, queryset):
            try:
                return fn(modeladmin, request, queryset)
            except TransitionNotAllowed:
                message = _("Transition not allowed.")
                messages.error(request, message)
        wrapped.short_description = short_description
        return wrapped
    return decorator

但是,如果应用了该装饰器,则只有最后一个动作可见(从应用装饰器的所有位置)。原因是wrapped.__name__将用作操作字典(reference)的键。

显然,解决此问题的一种方法是设置自定义__name__,如下所示:wrapped.__name__ = short_description。我不喜欢这种方法,因为它看起来有点像黑客。

您是否有更好的方法将装饰应用于行动?

1 个答案:

答案 0 :(得分:0)

我就是那样做的:

def add_short_description(short_description: str):
    def decorator(admin_action):
        def wrapper(*args, **kwargs):
            return admin_action(*args, **kwargs)
        wrapper.short_description = short_description
        return wrapper
    return decorator

然后在admin.py中输入

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    ...
    actions = [ ..., 'my_action', ...]

    @add_short_description('Some description')
    def my_action(self, request, queryset):
        ...