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)