Serializer with foreign key - GET and POST

2019-07-27 02:55发布

I currently have a model serializer with a foreign key field. I would like the related model to a serialized object rather than just an ID. I know this is possible by creating a serializer for the related model and doing

related_field = RelatedFieldSerializer()

However, how do I handle the case when creating/updating occurs for the main object? E.g. I want to create an instance of the main object but the related field will get sent as an object (not a pk) and won't refer to the existing foreign key, it will try to create a new object instead.

Hope this makes sense

2条回答
干净又极端
2楼-- · 2019-07-27 03:21

If you don't want to create the existing object, you can do something like this where you leverage PrimaryKeyRelatedField as documented here.

models.py

class Model1(models.Model):
    time = models.DateTimeField(auto_now=True)

class Model2(models.Model):

    model1= models.ForeignKey(Model1, on_delete=models.CASCADE)
    f1 = models.FloatField()

Then your serializers.py would look like:

class Model2Serializer(serializers.ModelSerializer):
    model1 = serializers.PrimaryKeyRelatedField(
        read_only=False, queryset=Model1.objects.all())

    class Meta:
        model = Model2
        fields = (
            'model1',
            'f1',
        )

Then posts can be made against the pk value of existing Model1 values in the database. Note, you could use other values than the pk value if needed. See this post.

查看更多
▲ chillily
3楼-- · 2019-07-27 03:35

You have to override the create and update methods of your serializer. The create method could look like this:

class MyModelSerializer(serializers.ModelSerializer):
    related_field = RelatedFieldSerializer()

    class Meta:
        model = MyModel
        fields = ('id', 'related_field')

    def create(self, validated_data):
        related_data = validated_data.pop('related_field')
        instance = MyModel.objects.create(**validated_data)
        RelatedModel.objects.create(my_model=instance, **related_data)
        return instance

For more information see the documentation about Writable nested representations

查看更多
登录 后发表回答