一尘不染

DRF:使用嵌套序列化程序进行简单的外键分配?

django

使用Django REST Framework,标准的ModelSerializer将允许通过将ID作为整数发布来分配或更改ForeignKey模型关系。

从嵌套序列化程序中获取此行为的最简单方法是什么?

注意,我只在谈论分配现有数据库对象,而不是嵌套创建。

过去,我在序列化程序中使用附加的“ id”字段以及自定义createupdate方法来解决这个问题,但是对我来说,这似乎是一个简单而频繁的问题,我很想知道最好的方法。

class Child(models.Model):
    name = CharField(max_length=20)

class Parent(models.Model):
    name = CharField(max_length=20)
    phone_number = models.ForeignKey(PhoneNumber)
    child = models.ForeignKey(Child)

class ChildSerializer(ModelSerializer):
    class Meta:
        model = Child

class ParentSerializer(ModelSerializer):
    # phone_number relation is automatic and will accept ID integers
    children = ChildSerializer() # this one will not

    class Meta:
        model = Parent

阅读 913

收藏
2020-03-25

共2个答案

一尘不染

最好的解决方案是使用两个不同的字段:一个用于读取,另一个用于写入。如果不做一些繁重的工作,就很难在一个领域中获得想要的东西。

只读字段将是你的嵌套序列化器(ChildSerializer在这种情况下),它将使你能够获得与期望的相同的嵌套表示形式。大多数人将其定义为just child,因为到此为止他们已经编写了前端,更改它会引起问题。

只写字段将是PrimaryKeyRelatedField,这是你通常用于根据对象的主键分配对象的字段。这不必是只写的,特别是如果你试图在接收到的内容和发送的内容之间保持对称性时,但这听起来可能最适合你。该字段应具有外键字段的source集合(child在此示例中),以便在创建和更新时对其进行正确分配。

2020-03-25
一尘不染

如果你想采用该方法并使用2个单独的字段,那么这是Kevin所讨论的内容的一个示例。

在你的模型中。py…

class Child(models.Model):
    name = CharField(max_length=20)

class Parent(models.Model):
    name = CharField(max_length=20)
    phone_number = models.ForeignKey(PhoneNumber)
    child = models.ForeignKey(Child)

然后是serializers.py …

class ChildSerializer(ModelSerializer):
    class Meta:
        model = Child

class ParentSerializer(ModelSerializer):
    # if child is required
    child = ChildSerializer(read_only=True) 
    # if child is a required field and you want write to child properties through parent
    # child = ChildSerializer(required=False)
    # otherwise the following should work (untested)
    # child = ChildSerializer() 

    child_id = serializers.PrimaryKeyRelatedField(
        queryset=Child.objects.all(), source='child', write_only=True)

    class Meta:
        model = Parent

设置source=child让child_id充当孩子会在默认情况下有它不能被重写(我们所期望的行为)。write_only=True使child_id可写,但防止它显示在响应以来的ID已经在显示出来ChildSerializer

2020-03-25