POST-запрос для вложенных объектов

У меня есть такие модели

class Survey(models.Model):
    name = models.CharField(max_length=120)
    ...


class Question(models.Model):
    survey = models.ForeignKey(Survey,
                               related_name='questions',
                               on_delete=models.CASCADE)
    ...


class Option(models.Model):
    question = models.ForeignKey(Question,
                                 related_name='options',
                                 on_delete=models.CASCADE)
    ...

Serializers выглядит следующим образом:

class OptionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Option
        exclude = ('question','id')


class QuestionSerializer(serializers.ModelSerializer):
    options = OptionSerializer(many=True)
    class Meta:
        model = Question
        exclude = ('survey',)


class SurveyDetailSerializer(serializers.ModelSerializer):
    creator = serializers.StringRelatedField(read_only=True)
    questions = QuestionSerializer(many=True)

    class Meta:
        model = Survey
        exclude = ('is_active',)

Запрос ясен, я получаю опрос со всеми вопросами и вариантами

views.py

class SurveyDetailView(generics.RetrieveAPIView):
    """Detail Survey view with all survey's questions"""
    queryset = Survey.objects.all()
    serializer_class = SurveyDetailSerializer

Result

{
    "id": 3,
    "creator": "nvbr",
    "questions": [
        {
            "id": 5,
            "options": [
                {
                    "text": "OPTION A"
                },
                {
                    "text": "OPTION B"
                }
            ],
            "answer_type": "single option",
            "text": "QUESTION 1?"
        }
    ],
    "name": "stackoverflow survey",
    "description": "Example",
    "created_at": "2021-09-23T13:07:19.679174Z"
}

но как я могу сделать POST для сохранения опроса, вопросов и вариантов? Или нужно всегда создавать отдельные конечные точки для всех моделей? Фронтенд SPA, если это важно

Ах, добро пожаловать в ограничения DRF.

В настоящее время способ работы с вложенными данными заключается в переопределении метода update в вашем сериализаторе:

serializers.py

class SurveyDetailSerializer(serializers.ModelSerializer):

    ...

    def update(self, instance, validated_data):

        # get the questions array:
        questions = validated_data.pop('questions')
        
        # create new questions, map to survey 
        ...

        # continue with regular update method:
        super().update(self, instance, validated_data)
Вернуться на верх