Отношение Django один ко многим для вызова API в restframework с использованием сериализаторов

#python #django #api #django-rest-framework

#python #django #API #django-rest-framework

Вопрос:

У меня есть две модели, которые представляют собой вопрос и набор вариантов, соответствующих этому вопросу. Я хочу объединить эти две модели, чтобы создать API, который показывает список вопросов с их выбором.

Это мои модели:

 class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField("date published")

    def __str__(self):
        return self.question_text


class Choice(models.Model):
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    question = models.ForeignKey(Question, on_delete=models.CASCADE)

    def __str__(self):
        return self.choice_text
 

Это мои сериализаторы

 class QuestionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Question
        fields = ('question_text',)


class ChoiceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Choice
        fields = ('choice_text','question',)


class QuestionWithAnswer(serializers.ModelSerializer):
    question = QuestionSerializer(many=True)

    class Meta:
        model = Choice
        fields = ('question',)
 

И это класс view

 @api_view(['GET', 'POST', ])
def getquestionWithChoices(request):
    question = Question.objects.all()
    serializer = QuestionWithAnswer
    return Response(serializer.data)
 

Я перепробовал много вещей, но не смог получить приведенный ниже результат.

   [
          {
            "id": 1,
            "question_text": "What's your name?",
            "pub_date": "2019-04-13T05:27:21Z",
            "choices": [
              {
                "id": 1,
                "choice_text": "fred",
                "votes": 0,
                "question": 1
              },
              {
                "id": 2,
                "choice_text": "bob",
                "votes": 0,
                "question": 1
              },
              {
                "id": 3,
                "choice_text": "rachel",
                "votes": 0,
                "question": 1
              }
            ]
          },
          {
            "id": 2,
            "question_text": "What's your age?",
            "pub_date": "2019-04-13T05:27:39Z",
            "choices": [
              {
                "id": 4,
                "choice_text": "15",
                "votes": 4,
                "question": 2
              },
              {
                "id": 5,
                "choice_text": "16",
                "votes": 2,
                "question": 2
              },
              {
                "id": 6,
                "choice_text": "17",
                "votes": 2,
                "question": 2
              }
            ]
          }
        ]
 

Ответ №1:

Вы неправильно создаете экземпляр сериализатора.

 @api_view(['GET', 'POST', ])
def getquestionWithChoices(request):
    questions = Question.objects.all()
    serializer = QuestionWithAnswer(questions, many=True)
    return Response(serializer.data)
 

и ваши сериализаторы также неверно определены:

 class ChoiceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Choice
        fields = ('id', 'votes', 'choice_text','question',)


class QuestionWithAnswer(serializers.ModelSerializer):
    choices = ChoiceSerializer(many=True)

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

Комментарии:

1. Я получаю сообщение об ошибке ниже после вашего предложенного редактирования: AttributeError: Получил AttributeError при попытке получить значение для поля choices в сериализаторе QuestionWithAnswer . Поле сериализатора может быть названо неправильно и не соответствовать какому-либо атрибуту или ключу Question экземпляра. Первоначальный текст исключения был следующим: объект ‘Question’ не имеет атрибута ‘choices’.

2. Спасибо за помощь. Я пропустил еще один параметр: related_name=’question’ в модели выбора. Пожалуйста, люди, ищущие ответ, могут добавить: вопрос = модели. ForeignKey(Вопрос, related_name=’вопрос’, on_delete=модели. КАСКАД)

3. спасибо за помощь. Извините, я не могу поддержать ваш ответ из-за моих низких баллов. Конечно, я сделаю это, как только получу свои очки.

Ответ №2:

Это мое мнение :

 @api_view(['GET', 'POST', ])
def getquestionWithChoices(request):
    questions = Question.objects.all()
    serializer = QuestionWithAnswer(questions, many=True)
    return Response(serializer.data)
 

Это мой сериализатор:

 class ChoiceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Choice
        fields = ('id', 'votes', 'choice_text',)


class QuestionWithAnswer(serializers.ModelSerializer):
    question = ChoiceSerializer(many=True)

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

Вот моя модель:

 class Choice(models.Model):
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    question = models.ForeignKey(Question,  related_name='question', on_delete=models.CASCADE)

    def __str__(self):
        return self.choice_text
 

Любой, кто ищет то же самое, может использовать это.Весь оставшийся код такой же, как вопрос.

Комментарии:

1. Не могли бы вы , пожалуйста , рассказать мне . Какое значение полей базы данных я должен вставить. Вручную @Simal