Micromegas
Micromegas

Reputation: 1689

Overwriting nested serializer's create method throws TypeError: create() got multiple values for keyword argument

I want to send data to my API. My data structure is nested. So I am trying to overwrite the create method following the docs and SO.

When sending data it gives me the following error:

TypeError: create() got multiple values for keyword argument 'graph'

My data structure looks like this:

{
        "project": "project1",
        "name": "Graph1",
        "description": "Graph belongs to Projekt1",
        "nodes": [
            {
                "id": 2,
                "name": "Node1 of Graph 1",
                "graph": 3
            }
        ]
    }

Her is what I am trying in my serializer (which is pretty standard I assume):

class GraphSerializer(serializers.ModelSerializer):

    nodes = NodeSerializer(many=True)

    class Meta:

        model   = Graph
        fields  = ('project',
                   'name',
                   'description',
                   'nodes',
                   )

    def create(self, validated_data):
        nodes_data = validated_data.pop('nodes')
        graph = Graph.objects.create(**validated_data)
        print(graph)
        for node_data in nodes_data:
            Node.objects.create(graph=graph,**node_data)

        return graph

The error is in the for loop. When I debug though and print graphit give me back just one Graph (Graph1). So I don't understand why I should get a multiple values error.

Here is more info if needed:

Node serializer

class NodeSerializer(serializers.ModelSerializer):

    id = serializers.IntegerField(required=False)

    class Meta:
        model  = Node
        fields = ('id',
                  'name',
                  'graph',
                  )
My models 

class Graph(models.Model):
    project         = models.ForeignKey(Project, on_delete=models.CASCADE)
    name            = models.CharField(max_length=120, blank=True)
    description     = models.CharField(max_length=400, blank=True)

    def __str__(self):
        return self.name

    @property
    def nodes(self):
        return self.node_set.all()

class Node(models.Model):
    name            = models.CharField(max_length=120, blank=True)
    graph           = models.ForeignKey(Graph, on_delete=models.CASCADE)

    def __str__(self):
        return self.name


Any help would be greatly appreciated. Thanks in advance!

PS: I also have another model which is almost the same as Node model. It is also attached to a Graph. So in the end I would like to send data with a double nested serializer. I guess I will ask this in a separate question, but if someone can point me to the right direction on how to do this I would be also very happy. Thanks

Upvotes: 0

Views: 530

Answers (1)

ruddra
ruddra

Reputation: 51988

I think the problem is you are sending the graph=graph keyword argument explicitly and there is another graph keyword argument inside node_data. I am assuming that from NodeSerializer. So, you need to remove graph from NodeSerializer fields to make it work or make the graph field read-only. Like this

class NodeSerializer(serializers.ModelSerializer):

    id = serializers.IntegerField(required=False)

    class Meta:
        model  = Node
        fields = ('id',
                  'name',
                  'graph',
                  )

       read_only_fields = ('graph',)

Upvotes: 2

Related Questions