Django休息框架一对一的关系

时间:2015-08-07 13:11:54

标签: 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()

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

{
  url: 'http://localhost/customs/1/',
  name: 'abc',
  age: 24,
  salary: 10000
}

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

2 个答案:

答案 0 :(得分:8)

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

阅读很容易

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

class ABSerializer(serializers.ModelSerializer):

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

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

写作......不受官方支持

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

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)

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

另一个选项

你也可以create a read-write flavor of SerializerMethodField,它既可以考虑吸气剂也可以考虑吸气剂,但最终可能会更加冗长。

希望有所帮助!

答案 1 :(得分:0)

我知道这是一篇旧帖子,但经过一些研究和阅读Django Rest Framework documentation 因此,快速搜索我发现您可以将“related_name”参数用于反向关系,如here

反向关系不会自动包含在 print(df.groupby('city')['sales'].mean()) ModelSerializer 类中。要包含反向关系,您必须将其显式添加到字段列表中。

例如:

HyperlinkedModelSerializer

您通常需要确保已为关系设置了适当的 class AlbumSerializer(serializers.ModelSerializer): class Meta: fields = ['tracks', ...] 参数,您可以将其用作字段名称。

例如:

related_name

如果您尚未为反向关系设置相关名称,则需要在 class Track(models.Model): album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE) ... 参数中使用自动生成的 related name

例如:

fields

此外,有关详细信息,请参阅 reverse relationships 上的 Django 文档。