Django JOIN嵌套模型外键与查找字段

时间:2017-10-01 13:57:57

标签: mysql django serialization django-rest-framework foreign-keys

我在 Django Rest Framework 中使用 2个模型

class Questions(models.Model):
    question = models.TextField()
    answer = models.TextField()
    timestamp = models.DateTimeField(auto_now_add=True)
    categories = models.ForeignKey(Categories, related_name="cat_questions", on_delete=models.CASCADE)


class QuestionnaireResult(models.Model):
    patient_info = models.ForeignKey(PatientInfo, related_name="+", on_delete=models.CASCADE)
    questions = models.ForeignKey(Questions, related_name="result_questions", on_delete=models.CASCADE)
    answer_given = models.TextField()
    timestamp = models.DateTimeField(auto_now_add=True)

两者都有序列化程序

class QuestionnaireResultSerailizer(serializers.ModelSerializer):
    class Meta:
        model = QuestionnaireResult
        fields = '__all__'


class QuestionsSerializer(serializers.ModelSerializer):
    result_questions = QuestionnaireResultSerailizer(many=True)

    class Meta:
        model = Questions
        fields ='__all__'

的观点:

class QuestionsViewSet(viewsets.ModelViewSet):
    queryset = Questions.objects.all()
    serializer_class = QuestionsSerializer


class QuestionnaireResultViewSet(viewsets.ModelViewSet):
    queryset = QuestionnaireResult.objects.all()
    serializer_class = QuestionnaireResultSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ['patient_info']

使用网址 - http://localhost:9000/api/questions/1,根据 question_id = 1 提供结果, result_questions 仅包含问题ID ==的嵌套记录1 即可。这是对的。

{
    "id": 1,
    "result_questions": [
        {
            "id": 1,
            "answer_given": "no",
            "timestamp": "2017-10-01T12:28:19.770454Z",
            "patient_info": 1,
            "questions": 1
        },
        {
            "id": 4,
            "answer_given": "no",
            "timestamp": "2017-10-01T13:13:19.658930Z",
            "patient_info": 2,
            "questions": 1
        }
    ],
    "question": "digestive ques 1",
    "answer": "yes",
    "timestamp": "2017-09-30T17:04:59.143857Z",
    "categories": 1
}

嵌套的json(result_questions)会返回所有patient_info ,其问题ID == 1 但我想添加一个更多过滤器(patient_info)就可以了。我只想通过传递查找字段来检索我想要检索的那些 patient_info

我想要的是那个。假设,我使用此网址http://localhost:9000/api/questions/1?patient_info=1

它返回 question_id == 1和patient_info == 1的响应。因此,响应应该是:

{
    "id": 1,
    "result_questions": [
        {
            "id": 1,
            "answer_given": "no",
            "timestamp": "2017-10-01T12:28:19.770454Z",
            "patient_info": 1,
            "questions": 1
        }
    ],
    "question": "digestive ques 1",
    "answer": "yes",
    "timestamp": "2017-09-30T17:04:59.143857Z",
    "categories": 1
}

2 个答案:

答案 0 :(得分:2)

您可以尝试serializermethodfield

class QuestionsSerializer(serializers.ModelSerializer):
    result_questions = serializers.SerializerMethodField()

    class Meta:
        model = Questions
        fields ='__all__'

    def get_result_questions(self, obj):
        qs = obj.result_questions.all()
        request = self.context.get('request')
        patient_info = request.GET.get('patient_info')
        if patient_info:
            qs = qs.filter(patient_info=patient_info)
        return QuestionnaireResultSerailizer(qs, many=True).data

答案 1 :(得分:1)

在视图中尝试在prefetch_related方法中使用get_object

def get_object(self, pk):
    try:
        return Questions.objects.prefetch_related(Prefetch('result_questions',  
            queryset=QuestionnaireResult.objects.filter(id=self.request.GET.get('patient_info')))).get(pk=pk)
    except Questions.DoesNotExist:
        raise Http404