django - django左外连接过滤不匹配记录
问题描述
目标是找出调查响应是否没有所有顶级问题的当前答案。
这可以通过获取响应的所有顶级问题来完成,然后过滤掉没有当前答案的问题。
我可以用 SQL 编写它,但是有没有办法可以使用 django 的 QuerySet 接口来实现它?
楷模
class Survey(Model):
...
class SurveySection(Model):
survey = ForeignKey(Survey, related_name='survey_sections')
class SurveyQuestion(Model):
survey_section = ForeignKey(SurveySection, related_name='survey_questions')
parent = ForeignKey('self') #questions can be nested
class SurveyResponse(Model):
survey = ForeignKey(Survey, related_name='survey_responses')
class SurveyAnswer(Model):
survey_response = ForeignKey(SurveyResponse, related_name='survey_answers')
survey_question = ForeignKey(SurveyQuestion, related_name='survey_answer')
is_current = BooleanField()
SQL
这应该找到响应所针对的调查的所有顶级问题,获取与这些问题匹配的当前答案并删除没有答案的问题。
select * from survey_surveyquestion question
join survey_surveysection section on section.id = question.survey_section_id
join survey_survey survey on survey.id = section.survey_id
join survey_surveyresponse response on response.survey_id = survey.id
left outer join survey_surveyanswer answer on answer.survey_question_id = question.id and answer.is_current = true
where response.id = 16
and answer.id is null
and question.parent is null
解决方案
您可以采用这种方法:
首先,获取父为 null 的问题数:
top_question_count = SurveyQuestion.objects.filter(parent__is_null=True).count()
然后,在过滤器中使用它:
from django.db.models imprt Count
SurveyResponse.objects.filter(
survey_answers__survey_question__parent__is_null=True,
is_current=True
).annotate(
top_level_questions=Count('survey_answers__survey_question')
).filter(
top_level_questions=top_question_count
)
推荐阅读
- python - 如何在追加模式下修复python覆盖文件?
- python - PyCharm:Jupyter 服务器已停止
- node.js - 头像已保存到 MongoDB,但没有成功消息和组件中的头像渲染,使用 React 和 Multer
- c# - 有没有办法在 C# 的构建时检查缺少的程序集?
- c# - 我应该为我的 REST API 的消费者提供客户端证书吗?
- groovy - JMeter:如何增加+1小时24次然后切换到第二天
- iis - Webdeploy 错误:“错误:源 (contentPath) 和目标 (appHostConfig) 与给定操作不兼容”
- java - Intellij:MapReduce 错误:线程“主”0 中的异常:没有这样的文件或目录
- ios - iOS 自动使用自定义阿拉伯/西里尔字体
- python - 来自脚本“test.py”的错误标头:错误标头:FISCAL_WEEK_NUMBER .,引用者:http://localhost/test.html