我有两个型号将使用相同的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_number
和Transaction.masked_number
。