如何在Django中为模型字段添加自定义方法



我有两个型号将使用相同的CardNumberField()来存储信用卡号。如何在字段中添加自定义方法以屏蔽卡号?

我已经创建了CardNumberField(),它继承自models.Charfield:

# CARD NUMBER FIELD
class CardNumberField(models.CharField):
description = _('card number')
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 19
super().__init__(*args, **kwargs)

然后导入CardNumberField()并在我的客户/型号中使用。py:

# CARD MODEL
class Card(models.Model):
number = CardNumberField()
...
def __str__(self):
return 'Card [{number}]'.format(number=self.number)

以及在我的事务/模型中。py

# TRANSACTION MODEL
class Transaction(models.Model):
card_number = CardNumberField()
...
def __str__(self):
return 'Transaction ...'

那么,如何将以下方法添加到我的CardNumberField()中以供我的两个模型使用呢?

def masked_number(self):
# display masked card number
number = self.number
return number[-4:].rjust(len(number), '#')

此外,我将如何在DRF序列化程序类中获取此字段方法?

您可以覆盖contribute_to_class方法,不仅贡献字段,还包括一个额外的方法:

from functools import partialmethod
def _mask_number(self, field):
number = getattr(self, field.attname)
return number[-4:].rjust(len(number), '#')
# CARD NUMBER FIELD
class CardNumberField(models.CharField):
description = _('card number')
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 19
super().__init__(*args, **kwargs)
defcontribute_to_class(self, cls, name, **kwargs):
super().contribute_to_class(cls, name, **kwargs)
setattr(
cls, f'masked_{self.name}',
partialmethod(_mask_number, field=self)
)

如果将字段foo添加到模型类,它将自动向该类添加masked_foo方法。因此,这也意味着,如果您有两个或多个CardNumberField,它将添加两个或更多个masked_foo方法。

使用抽象模型:

class ModelWithCardNumber(models.Model):
card_number = models.CharField(max_length=19)

@property
def masked_number(self):
return self.card_number[-4:].rjust(len(number), '#')

class Meta:
abstract = True

class Card(ModelWithCardNumber):
def __str__(self):
return 'Card [{number}]'.format(number=self.number)

class Transaction(ModelWithCardNumber):
def __str__(self):
return 'Transaction ...'

现在,在您的序列化程序中,您可以访问Card.masked_numberTransaction.masked_number

最新更新