如何在 functools.partialmethod 上设置属性?

How can I set an attribute on a functools.partialmethod?

我已将以下代码从 Django 2.2 移植到 Django 3.1,并将 django.utils.functional.curry 替换为 functools.partialmethod:

class CurrencyField(models.DecimalField):
    description = 'Currency amount'

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('max_digits', 9)
        kwargs.setdefault('decimal_places', 2)
        super().__init__(*args, **kwargs)

    def contribute_to_class(self, cls, name):
        super().contribute_to_class(cls, name)
        if hasattr(cls, '_get_value_as_currency'):
            curried = partialmethod(cls._get_value_as_currency, field=self)
            curried.admin_order_field = self.name
            curried.short_description = self.verbose_name
            setattr(cls, f'get_{self.name}_as_currency', curried)

该方法工作正常,但是 admin_order_fieldshort_description 属性不会像我使用 curry 时那样“坚持”该方法。

getattr(cls, f'get_{self.name}_as_currency').short_description
*** AttributeError: 'function' object has no attribute 'short_description'

是否可以在 partialmethod 上设置属性,或者我是否需要用其他机制替换它?

所以在一两个星期没有答案以及更多实验之后,我放弃了尝试让属性坚持 partialmethod 而是动态定义了一个局部函数,并且使用 Django 3.2 中新的 @admin.display 装饰器来设置管理属性,尽管如果没有语法糖也可以实现同样的效果:

    def contribute_to_class(self, cls, name):
        super().contribute_to_class(cls, name)
        if hasattr(cls, '_get_value_as_currency'):
            @admin.display(
                ordering=self.name,
                description=self.verbose_name,
            )
            def getter(obj):
                return obj._get_value_as_currency(self)
            setattr(cls, f'get_{self.name}_as_currency', getter)