Home > Net >  How to save a nested object in separate models in Django?
How to save a nested object in separate models in Django?

Time:11-26

I'm trying to save a nested object into two different tables in my Django app. I'm missing something because I get validation errors from the sub Model. The data in my events is not recognized and the serializer validation fails. Do I need to modify my serializer somehow or is there something wrong with my Models?

I have these two Models:

class Plan(models.Model):
    name = models.CharField(max_length=200)

class PlanEvent(models.Model):
    plan = models.ForeignKey(Plan, on_delete=models.CASCADE)
    done = models.BooleanField()
    title = models.CharField(max_length=100, blank=True)

Then I have these serializers for my Models:

class PlanEventSerializer(serializers.ModelSerializer):
    class Meta:
        model = PlanEvent
        fields = '__all__'


class PlanSerializer(serializers.ModelSerializer):
    events = PlanEventSerializer(many=True)

    class Meta:
        model = Plan
        fields  = ('name', 'events')

    def create(self, validated_data):
        events_validated_data = validated_data.pop('events')
        plan = Plan.objects.create(**validated_data)
        plan_event_serializer = self.fields['events']
        for p in events_validated_data:
            p['plan'] = plan
        events = plan_event_serializer.create(events_validated_data)
        return plan

In my views.py I do this:

class PlanView(APIView):
    permission_classes = [AllowAny,]
    serializer_class = PlanSerializer

    def post(self, request, format=None):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

I try to save a Plan and the PlanEvent into their own table with this payload:

{
  "name": "some name",
  "events": [
    {
      "done": false,
      "title": "some title"
    },
    {
      "done": true,
      "title": "some title"
    }
  ]
}

This gives me an error message 400 Bad Request every time:

    {
    "events": [
        {
            "plan": [
                "This field is required."
            ]
        },
        {
            "plan": [
                "This field is required."
            ]
        }
    ]
}

CodePudding user response:

The problem was, I had a mistake in here:

 for p in events_validated_data:
     p['plan'] = plan

It was supposed to be:

 for p in events_validated_data:
     p['id'] = plan

Also had to exclude the foreign key field from the serializer as Yery cs suggested.

CodePudding user response:

It seems, you need to pass plan primary key,not plan object in PlanSerializer.

for p in events_validated_data:
            p['plan'] = plan.id
  • Related