如何在 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_field
和 short_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)