【问题标题】:How to decorate admin actions in Django, action.__name__ used as dict key?如何在 Django 中装饰管理操作,action.__name__ 用作 dict 键?
【发布时间】:2017-05-04 20:45:12
【问题描述】:

为了避免重复,我决定装饰一些我在 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。不过我不喜欢这种方法,因为它看起来有点老套。

您有更好的方法来将装饰应用于动作吗?

【问题讨论】:

标签: python django python-decorators


【解决方案1】:

我就是这么弄的:

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):
        ...

【讨论】:

  • 在 Django 3.2 中我不得不扩展它,所以在 wrapper.short_description = short_description 下有 wrapper.__name__ = short_description
猜你喜欢
  • 1970-01-01
  • 2021-11-16
  • 2020-08-27
  • 2019-04-24
  • 2021-08-03
  • 2020-03-30
  • 2013-09-01
  • 2014-05-25
  • 1970-01-01
相关资源
最近更新 更多