Сериализатор с возможностью записи
У меня есть следующие наборы представлений и сериализаторы, настроенные для создания одного действия для публикации расписания с его шагами, но я получаю следующую ошибку.
class StepCreateSerializer(serializers.Serializer):
start_time = serializers.TimeField()
time = serializers.IntegerField()
def update(self, instance, validated_data):
pass
def create(self, validated_data):
print(validated_data)
return validated_data
class ScheduleCreateSerializer(serializers.Serializer):
name = serializers.CharField(max_length=100)
identifier = serializers.CharField(max_length=10)
steps = StepCreateSerializer(many=True)
def update(self, instance, validated_data):
pass
def create(self, validated_data):
steps_data = validated_data.get('steps', [])
schedule = Schedule.objects.create(**validated_data)
for step_data in steps_data:
Step.objects.create(schedule=schedule, **steps_data)
return schedule
class ScheduleViewSet(BaseViewSet):
queryset = Schedule.objects.all()
serializer_class = ScheduleSerializer
def create(self, request, *args, **kwargs):
ser = ScheduleCreateSerializer(data=request.data)
ser.is_valid(raise_exception=True)
ser.save()
return Response()
Я вызываю его со следующей полезной нагрузкой json с методом POST:
{
"name": "Schedule123",
"identifier": "S123",
"steps": [
{
"start_time": "07:21:00",
"time": 5,
"valve_actions": [
{
"start_state": true,
"end_state": false,
"valve": 2
},
{
"start_state": true,
"end_state": false,
"valve": 1
}
]
}
]
}
При вызове с полезной нагрузкой
возникает следующая ошибкаTypeError: Direct assignment to the reverse side of a related set is prohibited. Use steps.set() instead.
Модели следующие
class Schedule(models.Model):
identifier = models.CharField(max_length=10)
name = models.CharField(max_length=100)
class Step(models.Model):
start_time = models.TimeField()
time = models.IntegerField()
schedule = models.ForeignKey("manager.Schedule", on_delete=models.CASCADE, related_name="steps",
null=True)
Как создать шаги для расписания с помощью одного действия post? Я пытаюсь написать одно действие для отправки полезной нагрузки, и оно должно создавать шаги для расписания
Если вы поддерживаете вложенные представления с возможностью записи, вам нужно написать .create() метод, который обрабатывает сохранение нескольких объектов.
В вашем примере вы хотите определить ScheduleCreateSerializer таким образом:
class ScheduleCreateSerializer(serializers.Serializer):
name = serializers.CharField(max_length=100)
identifier = serializers.CharField(max_length=10)
steps = StepCreateSerializer(many=True)
def create(self, validated_data):
# use .pop() to remove steps from valiated_data
steps_data = validated_data.pop('steps', [])
schedule = Schedule.objects.create(**validated_data)
# your should use step_data not steps_data in the for loop
for step_data in steps_data:
Step.objects.create(schedule=schedule, **step_data)
# or a better optimization is to use bulk_create to save trips to DB
Step.objects.bulk_create([
Step(**data)
for data in steps_data
])
return schedule
Аналогично, если вы хотите использовать тот же сериализатор для поддержки обновлений, вам нужно будет определить метод update() в сериализаторе.