如何在Django中实现数据库存储信息的脱敏部分展示功能?
Django手机号脱敏展示实现方案
原有代码问题说明
- 自定义的
couple方法不是Django模型的内置方法,不会在数据保存/读取时自动触发,逻辑不会生效 - 脱敏逻辑不完整,仅截取了前6位字符,没有拼接掩码和末尾的保留字符
- 你定义的
num字段最大长度为7,无法容纳前6位+5个星号+末尾1位共12位的脱敏结果,会触发字段长度报错
实现方案
方案1:动态生成脱敏结果(推荐,无需额外存储字段)
不需要额外新增num字段,直接通过模型属性动态计算脱敏值,避免冗余存储和数据不同步问题,代码如下:
class Product(models.Model): number = models.CharField(max_length=25) @property def masked_number(self): # 先判断号码长度,避免索引越界报错 if len(self.number) >= 7: return f"{self.number[:6]}*****{self.number[-1]}" # 长度不符合要求时直接返回原内容 return self.number
在HTML模板中直接调用属性即可:{{ 实例对象.masked_number }}
方案2:脱敏结果存入数据库
如果你需要将脱敏后的结果持久化存储到num字段,重写模型的save方法即可,修改后代码如下:
class Product(models.Model): number = models.CharField(max_length=25) # 注意修改字段最大长度,适配脱敏后的字符长度 num = models.CharField(max_length=12, blank=True) def save(self, *args, **kwargs): if len(self.number) >= 7: self.num = f"{self.number[:6]}*****{self.number[-1]}" else: self.num = self.number super().save(*args, **kwargs)
每次保存实例时会自动计算并存储脱敏值,模板中调用{{ 实例对象.num }}即可展示。
注意事项
- 若存储的手机号格式不固定,建议先增加号码格式校验逻辑,避免索引取值报错
- 若使用方案2,已存在的历史数据需要手动执行一次批量更新,补全所有历史实例的
num字段值
内容的提问来源于stack exchange,提问作者Витя Корвус
相关产品推荐
相关产品推荐

