Django Rest Framework多层嵌套序列化

时间:2017-09-08 15:37:27

标签: django serialization nested django-rest-framework many-to-many

我有四个模型,我试图序列化为一个响应。我已经设法让前三个模型按照需要工作,我可以根据需要让最后两个模型工作但我不能在我的生活中获得最后一个关系在一个序列化响应中按需工作。感谢此时的任何想法,我不知道我是否应该专注于我的序列化器或视图。

models.py:

class Survey(models.Model):
    survey_name = models.CharField('survey name', max_length=100)
    survey_type = models.CharField('survey type', max_length=1)
    survey_category = models.CharField('survey category', max_length=1)
    questions = models.ManyToManyField(Question, through='SurveyDetail')
    date_created = models.DateTimeField('date created', auto_now_add=True)
    date_updated = models.DateTimeField('date updated', auto_now=True)

class SurveyDetail(models.Model):
    survey = models.ForeignKey(Survey, verbose_name='survey identifier')
    question = models.ForeignKey(Question, verbose_name='question identifier')
    question_number = models.IntegerField('question number', default=0)
    question_type = models.CharField('question type', max_length=1, default='M')
    question_quiz_mode = models.BooleanField('quiz mode', default=False)
    question_attributes = JSONField('question attributes', null=True, blank=True)
    date_created = models.DateTimeField('date created', auto_now_add=True)
    date_updated = models.DateTimeField('date updated', auto_now=True)

class Question(models.Model):
    question_text = models.CharField('question', max_length=200)
    date_created = models.DateTimeField('date created', auto_now_add=True)
    date_updated = models.DateTimeField('date updated', auto_now=True)

class Answer(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE, verbose_name='parent question identifier')
    answer_number = models.IntegerField('answer number', default=0)
    answer_text = models.CharField('answer text', max_length=200)
    correct_answer = models.BooleanField('quiz answer', default=False)
    date_created = models.DateTimeField('date created', auto_now_add=True)
    date_updated = models.DateTimeField('date updated', auto_now=True)

调查通过SurveyDetails提出多对多关系的问题。问题可以以不同的格式存在于多个调查中,这是SurveyDetails中引入其他字段的原因。最后一部分是Answers属于一对一问题。

serializers.py:

class AnswerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Answer
        fields = ('id', 'answer_number', 'answer_text', 
                  'correct_answer')

class QuestionSerializer(serializers.ModelSerializer):
    answers = AnswerSerializer(source='answer_set', many=True)

    class Meta:
        model = Question
        fields = ('id', 'question_text', 'answers')

class SurveyDetailSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.ReadOnlyField(source='question.id')
    text = serializers.ReadOnlyField(source='question.question_text')

    class Meta:
        model = SurveyDetail
        fields = ('id', 'text', 'question_number', 'question_type',
                  'question_quiz_mode', 'question_attributes')

class SurveySerializer(serializers.ModelSerializer):
    questions=SurveyDetailSerializer(source='surveydetail_set', many=True)

    class Meta:
        model = Survey
        fields = ('id', 'survey_name', 'survey_type', 'survey_category', 'questions')

我现在只处理两种观点,只是想在响应中获取整个调查。

views.py

class SurveyList(generics.ListCreateAPIView):
    queryset = Survey.objects.all()
    serializer_class = SurveySerializer

class QuestionList(generics.ListCreateAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

当我调用我的/调查网址时,我设法获得调查的所有内容,包括问题模型中的问题文本。但是,我无法让答案与他们的问题一起呈现内联。

/surveys response:
[
    {
        "id": 1,
        "survey_name": "Test",
        "survey_type": "T",
        "survey_category": "T",
        "questions": [
            {
                "id": 1,
                "text": "Does this work?",
                "question_number": 1,
                "question_type": "M",
                "question_quiz_mode": false,
                "question_attributes": null
            },
            {
                "id": 2,
                "text": "Does this still work?",
                "question_number": 2,
                "question_type": "M",
                "question_quiz_mode": false,
                "question_attributes": null
            },
            {
                "id": 3,
                "text": "Why?",
                "question_number": 3,
                "question_type": "M",
                "question_quiz_mode": false,
                "question_attributes": null
            },
            {
                "id": 4,
                "text": "Really?",
                "question_number": 4,
                "question_type": "M",
                "question_quiz_mode": false,
                "question_attributes": null
            }
        ]
    }
]

当我在Question上执行一个视图时,我可以得到问题和相关答案。

/questions response:
[
    {
        "id": 3,
        "question_text": "Why?",
        "answers": [
            {
                "id": 3,
                "answer_number": 1,
                "answer_text": "Because",
                "correct_answer": false
            },
            {
                "id": 4,
                "answer_number": 2,
                "answer_text": "Just Does",
                "correct_answer": false
            }
        ]
    },
    {
        "id": 4,
        "question_text": "Really?",
        "answers": [
            {
                "id": 5,
                "answer_number": 1,
                "answer_text": "Yes",
                "correct_answer": false
            },
            {
                "id": 6,
                "answer_number": 2,
                "answer_text": "No",
                "correct_answer": false
            }
        ]
    },
    {
        "id": 2,
        "question_text": "Does this still work?",
        "answers": [
            {
                "id": 7,
                "answer_number": 1,
                "answer_text": "Yes",
                "correct_answer": false
            },
            {
                "id": 8,
                "answer_number": 2,
                "answer_text": "No",
                "correct_answer": false
            }
        ]
    },
    {
        "id": 1,
        "question_text": "Does this work?",
        "answers": [
            {
                "id": 1,
                "answer_number": 1,
                "answer_text": "Yes",
                "correct_answer": false
            },
            {
                "id": 2,
                "answer_number": 2,
                "answer_text": "No",
                "correct_answer": false
            }
        ]
    }
]

我最终希望实现的是在请求/调查时与答案一致的答案。类似的东西:

Desired Response:
[
    {
        "id": 1,
        "survey_name": "Test",
        "survey_type": "T",
        "survey_category": "T",
        "questions": [
            {
                "id": 1,
                "text": "Does this work?",
                "answers": [
                    {
                        "id": 1,
                        "answer_number": 1,
                        "answer_text": "Yes",
                        "correct_answer": false
                    },
                    {
                        "id": 2,
                        "answer_number": 2,
                        "answer_text": "No",
                        "correct_answer": false
                    }
                ],
                "question_number": 1,
                "question_type": "M",
                "question_quiz_mode": false,
                "question_attributes": null
            },
            {
                "id": 2,
                "text": "Does this still work?",
                "answers": [
                    {
                        "id": 7,
                        "answer_number": 1,
                        "answer_text": "Yes",
                        "correct_answer": false
                    },
                    {
                        "id": 8,
                        "answer_number": 2,
                        "answer_text": "No",
                        "correct_answer": false
                    }
                ],
                "question_number": 2,
                "question_type": "M",
                "question_quiz_mode": false,
                "question_attributes": null
            }
        ]
    }
]

我很感激有关该主题的任何见解和建议。我确信这是一件非常直接的事情,我很想念,但我对DRF来说相对较新。经过3天的谷歌搜索和研究,我认为是时候问专家了。

1 个答案:

答案 0 :(得分:0)

试试这个:

class SurveyDetailSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.ReadOnlyField(source='question.id')
    text = serializers.ReadOnlyField(source='question.question_text')
    answers = serializers.SerializerMethodField()

    class Meta:
        model = SurveyDetail
        fields = ('id', 'text', 'answers', 'question_number', 'question_type',
              'question_quiz_mode', 'question_attributes')

    def get_answers(self, obj):
        return AnswerSerializer(obj.question.answer_set.all(), many=True).data