Как сохранить вложенный объект в отдельных моделях в Django?
Я пытаюсь сохранить вложенный объект в две разные таблицы в моем приложении Django. Я что-то упускаю, потому что получаю ошибки валидации от вложенной модели. Данные в моей 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 в их собственную таблицу с такой полезной нагрузкой:
{
"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.