M
M
Maxim Tarabrin2018-08-29 19:36:38
Django
Maxim Tarabrin, 2018-08-29 19:36:38

How to save a new object through a serializer with a nested serializer?

So the models are:

class Survey(models.Model):
    name = models.CharField(max_length=255, help_text="input survey name", verbose_name='survey name')
    description = models.TextField(blank=True,
                                   help_text="input description")
    creator = models.ForeignKey(User, models.CASCADE, help_text="creator survey")
    unique_url = models.CharField(max_length=200, null=True, unique=True, verbose_name='url')
    is_active = models.BooleanField(null=False, default=False)
    is_anonymous = models.BooleanField(null=False, default=False)
    have_answers = models.BooleanField(default=False)
    statuses = models.ManyToManyField(User, through='Status', related_name='statuses')
    created_at = models.DateTimeField(auto_now_add=True,null=True)
    answers_count = models.IntegerField(default=0)
    expiration_date = models.DateField(null=True, default=None, blank=True)

    class Meta:
        verbose_name = 'Опрос'

    def __str__(self):
        return "Survey. Name: %s, Description: %s" % (
            self.name, self.description)

class Question(models.Model):
    title = models.TextField(help_text="question title")
    required = models.BooleanField(null=False, default=False)
    survey = models.ForeignKey(Survey, models.CASCADE)
    def __str__(self):
        return "Question. Title: %s" % self.title

Serializers:
class QuestionSerializer(serializers.ModelSerializer):
    # answers = AnswerSerializer(many=True)
    title = serializers.CharField()
    required = serializers.BooleanField()
    survey = serializers.IntegerField(required=False)
    class Meta:
        model = Question
        fields = ('title',
                  'required',
                  'survey',
                  )

class SurveyCreateSerializer(serializers.ModelSerializer):
    questions = QuestionSerializer(many=True)
    class Meta:
        model = Survey
        fields = ('name',
                  'description',
                  'is_active',
                  'is_anonymous',
                  'expiration_date',
                  'questions'
                  )
    def generate_uuid(self):
        data = uuid.uuid4().hex
        return data
    def create(self, validated_data):
        questions = validated_data.pop('questions',[])
        validated_data['unique_url'] = self.generate_uuid()
        validated_data['creator'] = self.context['request'].user
        survey = Survey.objects.create(**validated_data)
        for question in questions:
            Question.objects.create(**question,survey=survey)
        return survey

view
class SurveyView(generics.CreateAPIView):
    serializer_class = SurveyCreateSerializer
    permission_classes = [IsAuthenticated]
    def generate_url(self):
        data = uuid.uuid4().hex
        return data
    def create(self, request, *args, **kwargs):
        survey_serializer = SurveyCreateSerializer(data=request.data,context={'request':request})
        survey_serializer.is_valid(raise_exception=True)
        self.perform_create(survey_serializer)
        headers = self.get_success_headers(survey_serializer.data)
        return Response(survey_serializer.data,status.HTTP_201_CREATED,headers=headers)

Error when passing data to controller:
Got AttributeError when attempting to get a value for field `questions` on serializer `SurveyCreateSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Survey` instance.
Original exception text was: 'Survey' object has no attribute 'questions'.
I do not understand how to solve, explain what is wrong.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question