【问题标题】:Additional field while serializing django rest framework序列化 django rest 框架时的附加字段
【发布时间】:2014-05-05 19:17:45
【问题描述】:

我是 django rest 框架的新手,并创建了一个示例 Employee 模型。

我的models.py

class Employees(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

我的serializers.py

class EmployeeSerializer(serializers.Serializer):
    class Meta:
        model = Employees
        fields = ('first_name','last_name')

这很好,但我想要一个额外的字段full_name,它将是first_name + last_name

如何在我的serializers.py 中定义这个新字段full_name

【问题讨论】:

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


    【解决方案1】:

    我在这里看到了两种方式(我更喜欢第一种方式,因为您可以在应用程序的其他部分重复使用它):

    将计算属性添加到您的模型并将其添加到您的序列化程序中 通过使用a readonly field with source=

    # models.py
    class Employees(models.Model):
        created = models.DateTimeField(auto_now_add=True)
        first_name = models.CharField(max_length=100)
        last_name = models.CharField(max_length=100)
    
        @property
        def full_name(self):
            return self.first_name + self.last_name
    
    # serializers.py
    class EmployeeSerializer(serializers.ModelSerializer):
        full_name = serializers.Field(source='full_name')
    
        class Meta:
            model = Employees
            fields = ('first_name','last_name', 'full_name')
    

    使用SerializerMethodField (您的模型不变)

    class EmployeeSerializer(serializers.ModelSerializer):
        full_name = serializers.SerializerMethodField('get_full_name')
    
        def get_full_name(self, obj):
            return obj.first_name + obj.last_name
    
        class Meta:
            model = Employees
            fields = ('first_name','last_name', 'full_name')
    

    【讨论】:

    • 对我来说,使用serializers.Field 会出错。如果未定义 to_representation 并且视图是只读的,serializers.ReadOnlyField 确实有效。
    • 我刚刚遇到了同样的问题(我不是序列化 Django 模型,而是另一个普通类),在我头疼了一段时间之后,我发现如果你使用它就可以正常工作full_name = serializers.ReadOnlyField(),即完全丢弃source参数。正如documentation says 关于source 参数:它默认为字段的名称。 Ans 即使它是一个方法(或一个属性),它也可以工作
    • 对我来说(django 1.11.13)不需要在序列化器中声明字段,只需在Model中声明并在Meta.fields中列出即可。
    【解决方案2】:

    SerializerMethodField 工作正常,我们也可以将数据存储在序列化器对象中,让方法get_field_name 使用它。

    例子:

    class MySerializer(serializers.ModelSerializer):
        statistic = serializers.SerializerMethodField()
    
        def __init__(self, instance=None, data=serializers.empty, statistic=None, **kwargs):
            super(MySerializer, self).__init__(instance=instance, data=data, **kwargs)
            self.statistic = statistic
    
        def get_statistic(self, obj):
            if self.statistic is None:
                return serializers.empty
            return self.statistic.get(obj.id, {})
    

    【讨论】:

      【解决方案3】:

      假设Employee是登录用户,那么我们大多数人都会使用django.auth.User,我将分享Employee如何实现为另一个Profile(django用户的扩展)。还添加了full_name.read_onlyfirst_name.write_onlylast_name.write_only

      # models.py
      class Employee(models.Model):
          """User Profile Model"""
          user = models.OneToOneField('auth.User')
      
      # serializers.py
      class EmployeeSerializer(serializers.HyperlinkedModelSerializer):
          username = serializers.CharField(source='user.username')
          email = serializers.EmailField(source='user.email')
      
          first_name = serializers.CharField(
                  source='user.first_name', write_only=True)
          last_name = serializers.CharField(
                  source='user.last_name', write_only=True)
          name = serializers.CharField(
                  source='user.get_full_name', read_only=True)
      
      
          class Meta:
              model = Employee
              fields = (
                  'url', 'username', 'email',
                  'first_name', 'last_name', 'name')
              depth = 1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-02
        • 2018-10-14
        • 2015-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-07
        相关资源
        最近更新 更多