序列化django休息框架时的附加字段

use*_*619 44 django django-models django-rest-framework

我是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)
Run Code Online (Sandbox Code Playgroud)

我的serializers.py:

class EmployeeSerializer(serializers.Serializer):
    class Meta:
        model = Employees
        fields = ('first_name','last_name')
Run Code Online (Sandbox Code Playgroud)

这工作正常,但我想要一个额外的字段full_name,这将是first_name + last_name.

如何定义这个全新的领域full_name,我serializers.py

Den*_*ehl 73

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

将计算属性添加到模型中,并 使用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

#serializes.py
class EmployeeSerializer(serializers.ModelSerializer):
    full_name = serializers.Field(source='full_name')

    class Meta:
        model = Employees
        fields = ('first_name','last_name', 'full_name')
Run Code Online (Sandbox Code Playgroud)

通过使用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')
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,使用`serializers.Field`会出错.如果没有定义`to_representation`并且视图是只读的,`serializers.ReadOnlyField`确实有效. (5认同)
  • 对我来说(django 1.11.13)不需要在序列化器中声明该字段,只需在模型中声明它并在Meta.fields中列出它即可。 (3认同)
  • 我刚刚遇到了同样的问题(我没有序列化一个Django模型,而是另一个普通类)并且在我用了一段时间之后我发现它已经发现它可以正常使用`full_name = serializers.ReadOnlyField() `,即完全丢弃`source`参数.正如[文档说明](http://www.django-rest-framework.org/api-guide/fields/)关于`source`参数:它默认为字段的名称.Ans即使它是一种方法(或属性)也可以工作 (2认同)

Yeo*_*Yeo 7

假设Employee是登录用户,那么我们大多数人都会使用django.auth.User,我将分享如何Employee实现为另一个Profile(django User的扩展)。还加上full_name.read_only, first_name.write_only, 和last_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
Run Code Online (Sandbox Code Playgroud)


Cra*_*Cai 5

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, {})
Run Code Online (Sandbox Code Playgroud)