Django休息框架一对一的关系

Ans*_*rta 8 python django rest django-rest-framework

所以我有以下模型:

class A(models.Model):
  name = models.CharField()
  age = models.SmallIntergerField()

class B(models.Model):
  a = models.OneToOneField(A)
  salary = model.IntergerField()
Run Code Online (Sandbox Code Playgroud)

现在我想为那两个创建一个休息终点,因为它们是一对一的.所以我想跟随得到

{
  url: 'http://localhost/customs/1/',
  name: 'abc',
  age: 24,
  salary: 10000
}
Run Code Online (Sandbox Code Playgroud)

同样,我想创建记录并更新.请让我知道如何在django rest framework 3中实现这一目标.

dde*_*eny 11

我刚遇到同样的问题,将响应结构与底层模型结构联系起来确实很有用.这是我的看法:

阅读很容易

Serializer字段有一个source参数,可以使用虚线名称来遍历属性.

class ABSerializer(serializers.ModelSerializer):

    class Meta:
        model = A
        fields = ['name', 'age', 'salary']

    salary = serializer.IntegerField(source='b.salary') # this is your related_name
Run Code Online (Sandbox Code Playgroud)

写作是......没有得到官方支持

验证的数据将显示嵌套结构,标准的创建和更新方法将阻止尝试将数据字典分配给OneToOneField.好消息是您可以通过覆盖创建和更新方法来解决它.这是更新的示例:

class ABSerializer(serializers.ModelSerializer):

    class Meta:
        model = A
        fields = ['name', 'age', 'salary']
        related_fields = ['b']

    salary = serializer.IntegerField(source='b.salary') # this is your related_name

    def update(self, instance, validated_data):
        # Handle related objects
        for related_obj_name in self.Meta.related_fields:

            # Validated data will show the nested structure
            data = validated_data.pop(related_obj_name)
            related_instance = getattr(instance, related_obj_name)

            # Same as default update implementation
            for attr_name, value in data.items():
                setattr(related_instance, attr_name, value)
            related_instance.save()
        return super(ABSerializer,self).update(instance, validated_data)
Run Code Online (Sandbox Code Playgroud)

当然,这个例子非常简单,不做任何异常处理,也不能使用更深层次的嵌套对象......但是你明白了.

另外一个选项

您还可以创建SerializerMethodField的读写风格,它将同时考虑getter和setter,但最终可能会更加冗长.

希望有所帮助!