I have models like this
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 looks like:
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',)
GET request is clear, i get survey with all questions and options
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"
}
but how can I make POST to save Survey, Questions and Options? Or should I always create separate endpoints for all models? SPA frontend if it important
CodePudding user response:
Ah, welcome to the limitations of DRF.
Presently, the way to work with nested data is by overriding the update method on your serializer:
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)