如何在 Django 的单独模型中保存嵌套对象?

How to save a nested object in separate models in Django?

我试图在我的 Django 应用程序中将嵌套对象保存到两个不同的 table 中。我遗漏了一些东西,因为我从子模型中得到了验证错误。我的 events 中的数据无法识别,序列化程序验证失败。我需要以某种方式修改我的序列化器还是我的模型有问题?

我有这两个型号:

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)

然后我的模型有这些序列化程序:

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

在我的 views.py 中,我这样做:

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)

我尝试使用以下负载将计划和 PlanEvent 保存到它们自己的 table 中:

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

这每次都会给我一个错误信息 400 Bad Request:

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

看来,您需要传递计划主键,而不是PlanSerializer中的计划对象。

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

问题是,我在这里犯了一个错误:

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

应该是:

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

还必须按照 Yery cs 的建议从序列化程序中排除外键字段。