带有查找字段的嵌套模型外键上的 Django JOIN
Posted
技术标签:
【中文标题】带有查找字段的嵌套模型外键上的 Django JOIN【英文标题】:Django JOIN on nested model Foreign key with look up field 【发布时间】:2018-03-12 19:00:08 【问题描述】:我在 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']
使用 URL - http://localhost:9000/api/questions/1
,它根据 question_id = 1 给出结果,result_questions 仅包含那些具有 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
但上面 nested json (result_questions) 返回 all patient_info 其中有 questions id == 1 但我想添加一个更多过滤器(患者信息) 就可以了。我只想要那些我想通过传递为查找字段来检索的患者信息。
我想要的是那个。假设,我使用这个网址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
【问题讨论】:
也请发表您的看法 @JahongirRahmonov 已发布视图。 【参考方案1】:你可以试试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
【讨论】:
谢谢。有效。你能帮我找到学习django rest框架的交互式教程吗? 很高兴为您提供帮助。我是通过django-angularjs-tutorial开始学习drf的 有一个问题。如果我使用serializers.SerializerMethodField()
。我不能做POST
请求。它抛出错误 - "errors": "'NoneType' object has no attribute 'GET'"
对于发布操作,如果使用 SerializerMethodField
,则需要覆盖 create
方法
或尝试理解@neverwalkaloner 的答案并修复错误【参考方案2】:
在视图中尝试在get_object
方法中使用prefetch_related
:
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
【讨论】:
它抛出 -get_object() takes exactly 2 arguments (1 given)
以上是关于带有查找字段的嵌套模型外键上的 Django JOIN的主要内容,如果未能解决你的问题,请参考以下文章
django模型中, 外键字段使用to_filed属性 指定到所关联主表的某个字段
Django Rest Framework:具有通用外键的可写嵌套序列化程序