Django / DRF — Получить поле связанной модели

#python #django #django-rest-framework

Вопрос:

каждый. Что я хочу, так это получить поле связанной модели с помощью сериализатора. У меня есть 2 модели:

 class Question(models.Model):
    question_text = models.CharField(max_length=200)
    def __str__(self):
        return self.question_text    



class Test(models.Model):
    test_name = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    question = models.ManyToManyField(Question, related_name='tests')
    def __str__(self):
        return self.test_name
 

Почему я использовал ManyToManyField?
Потому что я последовал сюда:
https://medium.com/django-rest/lets-build-a-basic-product-review-backend-with-drf-part-1-652dd9b95485

Теперь я могу делать что-то вроде: введите описание изображения здесь

Но я хочу получить question_text в ответ. Что я пытался:

 class TestSerializer(serializers.HyperlinkedModelSerializer):
    question_text = serializers.CharField(read_only=True, source="question.question_text")
    class Meta:
        model = Test
        fields = ['pk', 'test_name', 'pub_date', 'question_text']
        expandable_fields = {
 'question': (QuestionSerializer, {'many': True})
}
 

Но оно вернулось:

введите описание изображения здесь

Я понимаю, что проблема может быть в отношениях с БД, но я не могу ее понять. Заранее спасибо!

Ответ №1:

Используйте вложенный сериализатор:

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

class TestSerializer(serializers.ModelSerializer):
    question = QuestionSerializer(many=True)
    class Meta:
        model = Test
        fields = ['pk', 'test_name', 'pub_date', 'question']
 

Ответ №2:

Есть два способа сделать это, я не знаю, какой из них лучше, но это они 1 — создайте отдельный сериализатор для вопроса и имени, связанного с assgin, в моделях.пай ему

 class QuestionSerializer(serializers.HyperlinkedModelSerializer):
    
    class Meta:
        model = Test
        fields = "__all__"




class TestSerializer(serializers.HyperlinkedModelSerializer):
    tests = QuestionSerializer(many=True) ## related_name
    class Meta:
        model = Test
        fields = ['pk', 'test_name', 'pub_date', 'tests']


  
 

2 — использование сериализаторов.SerializerMethodField()

 class TestSerializer(serializers.HyperlinkedModelSerializer):
        question = serializers.SerializerMethodField() 
        class Meta:
            model = Test
            fields = ['pk', 'test_name', 'pub_date', 'question']
        def get_question(self, obj):
            question = obj.tests.all()
            serilaizer = QuestionSerializer(question, many=True)
            return serilaizer.data