按相关字段过滤 django 查询集

时间:2021-02-11 09:57:24

标签: django django-rest-framework

我有一个从 generics.RetrieveUpdateDestroyAPIView 继承的 DRF QuestionSet 视图

我也有 2 个模型(简化版):

class Question(models.Model):
    question_set = models.ForeignKey(QuestionSet, related_name="questions")
    is_archived = models.BooleanField(default=False)
    ...other_fields

class QuestionSet(models.Model):

    ...fields

现在我需要在视图中返回一个 question_set 对象,该对象只有 True 的问题。像这样:

"id": 1,
"questions": [
        {
            "id": 1,
            "isArchived": true
        },
        {
            "id": 1,
            "isArchived": true
        },
        {
            "id": 1,
            "isArchived": true
        },
]

我正在尝试覆盖视图中的 get_object() 方法以返回这些值。那么我该如何实现呢?

3 个答案:

答案 0 :(得分:1)

首先,您可以覆盖 get_queryset 方法来过滤查询集:

def get_queryset(self):
    return QuestionSet.objects.select_related('questions').filter(is_archived=True)

接下来您必须修改序列化程序类以获得所需的输出格式。尝试使用 nested serializers

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

class QuestionSetSerializer(serializers.ModelSerializer):
    questions = QuestionSerializer(many=True, read_only=True)

    class Meta:
        model = QuestionSet
        fields = ['id']

答案 1 :(得分:1)

结果比我想象的要棘手。我建议使用 SerializerMethodField

#content of serializers.py

from rest_framework import serializers
from .models import Question, QuestionSet


class QuestionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Question
        fields = ['id', 'is_archived', 'question_set']


class QuestionSetSerializer(serializers.ModelSerializer):
    inactive_questions = serializers.SerializerMethodField()

    class Meta:
        model = QuestionSet
        fields = ['id', 'inactive_questions']

    def get_inactive_questions(self, obj):
        active_questions = obj.questions.filter(is_archived=True)
        return QuestionSerializer(active_questions, many=True, read_only=True).data

更多详细信息可以在Github repo

中找到

答案 2 :(得分:1)

我能够通过覆盖 qs 来解决它:

return self.queryset.prefetch_related(Prefetch('questions', 
                               queryset=Question.objects.filter(is_archived=True)))