0

I have two models

class Answer(models.Model):
    answer = models.TextField()
    created_at = models.DateTimeField(editable=False, default=timezone.now)
    updated_at = models.DateTimeField(default=timezone.now)
    user = models.ForeignKey('users.CustomUser', on_delete=models.PROTECT)
    question = models.ForeignKey('Question', on_delete=models.PROTECT)
    number_of_points = models.IntegerField(default=0)
    moderate_status = models.BooleanField(default=False)

and

class Question(models.Model):
    question_subject = models.TextField()
    question_text = models.TextField(default=None, null=True, blank=True)
    slug = models.SlugField(max_length=128, unique=True, null=False, editable=False)
    created_at = models.DateTimeField(editable=False, default=timezone.now)
    updated_at = models.DateTimeField(default=timezone.now)
    user = models.ForeignKey('users.CustomUser', on_delete=models.PROTECT)
    animal = models.ForeignKey('animals.Animal', on_delete=models.PROTECT)

serializers.py

class QuestionDetailSerializer(serializers.ModelSerializer):
    answers = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = Question
        fields = '__all__'

views.py

class QuestionsDetailView(generics.ListAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionsSerializer

    def get_queryset(self):
        return super().get_queryset().filter(
            id=self.kwargs['pk']
        )

url.py

path('questions/<int:pk>', QuestionsDetailView.as_view()),

And i want to combine 2 queryset, one being already that filters the question by pk provided in the url, and the other queryset i'd like to give is Answer.objects.all().filter(question__id='pk'). Essentially i want to show all the questions with answers to a particular question.

2 Answers 2

1

I strongly suggest to use relationships anywhere you can.

Add related_name to Answer.question in models.py:

class Answer(models.Model):
    ...
    question = models.ForeignKey('Question', on_delete=models.PROTECT, related_name='answers')

If id is enough in serializer, then in serializers.py:

class QuestionDetailSerializer(serializers.ModelSerializer):
    # this is not needed anymore: answers = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = Question
        fields = ['question_subject ', 'question_text', ..., 'answers`]

But you can also create a function of model that you can include in similar way:

class Question(models.Model):
    ...
    def get_answers(self):
        return [answer.answer for answer in self.answers.all()]    # it will return a list of TextFields of answers

serializers.py:

class QuestionDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Question
        fields = ['question_subject ', 'question_text', ..., 'get_answers`]
Sign up to request clarification or add additional context in comments.

Comments

1

You won't exactly combine 2 queryset from different table. But you can use nested serializer.

class AnswerSerializer(serializers.ModelSerializer):

    class Meta:
        model = Anwser
        fields = ['id', ...]

class QuestionDetailSerializer(serializers.ModelSerializer):
    answer_set = AnswerSerializer(many=True, read_only=True)

    class Meta:
        model = Question
        fields = ['id', ..., 'answer_set']

# OR


class QuestionDetailSerializer(serializers.ModelSerializer):

    class Meta:
        model = Question
        fields = ['id']
    
    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['answers'] = AnswerSerializer(many=True, instance=instance.anwser_set.all()).data
        return data

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.