【问题标题】:Modifying value on serialization - Django Rest Framework修改序列化的值 - Django Rest Framework
【发布时间】:2018-10-29 20:06:22
【问题描述】:

我有一个包含敏感数据的模型,比如说一个社会保险号,我想在序列化时转换该数据以仅显示最后四位数字。

我存储了完整的社会安全号码:123-45-6789。 我希望我的序列化程序输出包含:***-**-6789

我的模特:

class Employee (models.Model):

    name  = models.CharField(max_length=64,null=True,blank=True)
    ssn   = models.CharField(max_length=16,null=True,blank=True)

我的序列化器:

class EmployeeSerializer(serializers.ModelSerializer):

    id = serializers.ReadOnlyField()

    class Meta:
        model = Employee

        fields = ('id','ssn')

        read_only_fields = ['id']

【问题讨论】:

    标签: python django django-models django-rest-framework


    【解决方案1】:

    详细说明@dhke 的答案,如果您希望能够重用此逻辑来修改跨多个序列化器的序列化,您可以编写自己的字段并将其用作序列化器中的字段,例如:

    from rest_framework import serializers
    from rest_framework.fields import CharField
    from utils import mask_ssn
    
    
    class SsnField(CharField):
        def to_representation(self, obj):
            val = super().to_representation(obj)
            return mask_ssn(val) if val else val
    
    
    class EmployeeSerializer(serializers.ModelSerializer):
        ssn = SsnField()
    
        class Meta:
            model = Employee
            fields = ('id', 'ssn')
            read_only_fields = ['id']
    

    您还可以扩展其他字段,例如 rest_framework.fields.ImageField 以自定义图像 URL 的序列化方式(如果您在图像之上使用图像 CDN 以对图像应用转换,这会很好)。

    【讨论】:

      【解决方案2】:

      如果您不需要更新 ssn,只需使用 SerializerMethodField 隐藏字段并在序列化程序上定义 get_ssn(self, obj)

      否则,最直接的方法可能就是覆盖.to_representation()

      def to_representation(self, obj):
          data = super(EmployeeSerializer, self).to_representation(obj)
          data['ssn'] = self.mask_ssn(data['ssn'])
          return data
      

      请根据需要添加特殊情况处理 ('ssn' in data)。

      【讨论】:

      • mask_ssn 来自哪里?
      • @shahriar-rahman-zahin 未显示,它必须在序列化程序(或任何地方)上定义才能按要求执行屏蔽。基本上就是上面的get_ssn()
      【解决方案3】:

      你可以使用SerializerMethodField:

      class EmployeeSerializer(serializers.ModelSerializer):
      
          id = serializers.ReadOnlyField()
          ssn = SerializerMethodField() 
      
          class Meta:
              model = Employee
      
              fields = ('id','ssn')
      
              read_only_fields = ['id']
      
          def get_ssn(self, obj):
               return '***-**-{}'.format(obj.ssn.split('-')[-1]
      

      【讨论】:

      • 非常感谢,搜索了几个小时!
      猜你喜欢
      • 2020-07-23
      • 1970-01-01
      • 2013-09-12
      • 1970-01-01
      • 1970-01-01
      • 2015-06-29
      • 2015-01-12
      • 2016-07-21
      • 2015-12-13
      相关资源
      最近更新 更多