Sql 如何使用Django ORM从三个相互连接的模型进行这个非常复杂的查询?

Sql 如何使用Django ORM从三个相互连接的模型进行这个非常复杂的查询?,sql,django,django-orm,Sql,Django,Django Orm,大家好。希望你做得很好。我是一个Django新手,试图学习RESTful开发的基础知识,同时帮助进行一个小型应用程序项目。我们目前希望我们的一些模型根据我们提交给他们的数据,通过使用Django ORM和一些模型与OneToMany关系共享的字段进行相应的更新。目前,有一个非常困难的查询,我必须做我的一个字段自动更新给定的过滤器。首先,让我解释一下模型。这不是真的,而是一个应该工作相同的doppleganger: 首先,我们有一个报告模型,它是教师对学生的报告: class Report(mod

大家好。希望你做得很好。我是一个Django新手,试图学习RESTful开发的基础知识,同时帮助进行一个小型应用程序项目。我们目前希望我们的一些模型根据我们提交给他们的数据,通过使用Django ORM和一些模型与OneToMany关系共享的字段进行相应的更新。目前,有一个非常困难的查询,我必须做我的一个字段自动更新给定的过滤器。首先,让我解释一下模型。这不是真的,而是一个应该工作相同的doppleganger:

首先,我们有一个
报告
模型,它是教师对学生的报告:

class Report(models.Model): 

    status = models.CharField(max_length=32, choices=Statuses.choices, default=Statuses.created,)
    student = models.ForeignKey(Student, on_delete=models.CASCADE,)
    headroom_teacher = models.ForeignKey(TeacherStaff, on_delete=models.CASCADE,)

    # Various dates
    results_date = models.DateTimeField(null=True, blank=True)
    report_created = models.DateTimeField(null=True, blank=True)
    .
    #Other fields that don't matter
这里我们有两个相关的模型,它们是
学生
教师净空
。没有必要展示他们的模型,但是他们与下两个模型的关系非常重要。我们还有一个
考试
模型:

class Exams(models.Model):

    student = models.ForeignKey(student, on_delete=models.CASCADE,)     
    headroom_teacher = models.ForeignKey(TeacherStaff, on_delete=models.CASCADE,)
            
    # Various dates
    results_date = models.DateTimeField(null=True, blank=True)
    initial_exam_date = models.DateTimeField(null=True, blank=True)
    .
    #Other fields that don't matter
正如你所看到的,这个应用程序的目的类似于报告学生在完成一些考试后的表现,每个报告都是由老师为特定学生做的,关于他在这些考试中的表现。最后,我们有一个名为
StudentMood
的最终模型,旨在展示学生在考试状态下的感受:

class StudentMood(models.Model):

    report = models.ForeignKey(Report, on_delete=models.CASCADE,)
    student_status = models.CharField(
        max_length=32, choices=Status.choices,
        default=None, null=True, blank=False)
    headroom_teacher = models.ForeignKey(TeacherStaff, on_delete=models.CASCADE,)
有了这三个模型,我们就找到了问题的症结所在。我们的一个可能的
学生状态
选项是
对结果的焦虑
,我们相信学生在完成考试并等待结果时会有这种感觉

我想使用自定义管理器自动设置我的
学生\ U状态
,该管理器会考虑完成报告的日期或输入数据的日期。我相信这可以通过考虑
初始考试日期
进行查询来实现

我已经设置了自定义管理器,唯一缺少的就是这个查询。我别无选择,只能用Django的ORM。但是,我提出了一个近似的原始SQL查询,我不确定它是否正常:

SELECT student_mood.id AS student_mood_id FROM
school_student_mood LEFT JOIN
school_reports report
ON student_mood.report_id = report.id AND student_mood.headroom_teacher_id = report.headroom_teacher_id
JOIN school_exams exams
ON report.headroom_teacher_id = exams.headroom_teacher_id 
AND report.student_id = exams.student_id
AND exams.results_date > date where the student_mood or report data is entered, I guess 

这就是我来寻求帮助的原因。有人能解释一下如何将其转换为一个查询吗?

没有环境设置,也不知道您想要从数据中得到什么。这是一个良好的开端

一般来说,Django ORM不适合这些类型的查询,尝试使用select_相关或预取会导致非常复杂和低效的查询

我发现在Django中实现这些类型的查询的最佳方法是将每个谜题分解为一个查询,该查询返回一个ID“列表”,您可以在子查询中使用这些ID

然后你继续工作,直到你有你的最终输出

从django.db.models导入子查询
#抓取成绩日期大于特定日期的任何考试的学生。
学生\考试\子查询=exam.objects.filter(
结果\u日期\u gt=时区。现在()
).values\u list('student\u id',flat=True)
#抓住所有与报告相关的学生情绪,这些报告与学生焦虑的“考试”相关
student\u mood\u子查询=StudentMood.objects.filter(
学生(焦虑),,
报告\学生\子查询(学生\考试\子查询)
).values\u list('report\u id',flat=True)
#获取最终的学生名单
Student.objects.values\u list('id',flat=True).过滤器(
报告\uuuuu id\uuuuu in=子查询(学生\u情绪\u子查询)
)

现在,我怀疑这是否会开箱即用,但这确实是为了让您了解如何以一种未来开发人员可以阅读且最高效(db-wise)的方式来解决这个问题。

无需环境设置,也不需要真正了解您想要从数据中得到什么。这是一个良好的开端

一般来说,Django ORM不适合这些类型的查询,尝试使用select_相关或预取会导致非常复杂和低效的查询

我发现在Django中实现这些类型的查询的最佳方法是将每个谜题分解为一个查询,该查询返回一个ID“列表”,您可以在子查询中使用这些ID

然后你继续工作,直到你有你的最终输出

从django.db.models导入子查询
#抓取成绩日期大于特定日期的任何考试的学生。
学生\考试\子查询=exam.objects.filter(
结果\u日期\u gt=时区。现在()
).values\u list('student\u id',flat=True)
#抓住所有与报告相关的学生情绪,这些报告与学生焦虑的“考试”相关
student\u mood\u子查询=StudentMood.objects.filter(
学生(焦虑),,
报告\学生\子查询(学生\考试\子查询)
).values\u list('report\u id',flat=True)
#获取最终的学生名单
Student.objects.values\u list('id',flat=True).过滤器(
报告\uuuuu id\uuuuu in=子查询(学生\u情绪\u子查询)
)

现在我怀疑这是否能开箱即用,但这确实是为了让你了解如何以一种未来开发者可读且最高效(db-wise)的方式来解决这个问题。

所以,我遇到的问题是,学校每个阶段都有考试周期,而且很难仅检索本周期的学生报告。假设我们有以下数据库:

+-----------+-----------+----------------+-------------------+-------------------+------------------+
|  Student  | Report ID | StudentMood ID | Exam Cycle Status | Initial Exam Date | Report created a |
+-----------+-----------+----------------+-------------------+-------------------+------------------+
| Student 1 |         1 |              1 | Done              | 01/01/2020        | 02/01/2020       |
| Student 2 |         2 |              2 | Done              | 01/01/2020        | 02/01/2020       |
| Student 1 |         3 |              3 | On Going          | 02/06/2020        | 01/01/2020       |
| Student 2 |         4 |              4 | On Going          | 02/06/2020        | 01/01/2020       |
+-----------+-----------+----------------+-------------------+-------------------+------------------+
显然,我想把我的查询限制在这个周期内,就像这样:

+-----------+-----------+----------------+-------------------+-------------------+------------------+
|  Student  | Report ID | StudentMood ID | Exam Cycle Status | Initial Exam Date | Report created a |
+-----------+-----------+----------------+-------------------+-------------------+------------------+
| Student 1 |         3 |              3 | On Going          | 02/06/2020        | 01/01/2020       |
| Student 2 |         4 |              4 | On Going          | 02/06/2020        | 01/01/2020       |
+-----------+-----------+----------------+-------------------+-------------------+------------------+
现在,您的答案,
trent
,确实很有用,但我仍然在上面的形式中存在检索问题:

qs_exams = Exams.objects.filter(initial_exam_date__gt=now()).values_list('student__id', flat=True)
qs_report = Report.objects.filter(student__id__in=qs_exams).values_list('id', flat=True)
qs_mood = StudentMood.objects.select_related('report') \
.filter(report__id__in=qs_report).order_by('report__student_id', '-created').distinct()

但这个问题仍然让我了解了整个学年的学生情绪。所以,有什么想法吗?

所以,我遇到的问题是,学校每节课都有考试周期,而且很难检索到本周期的学生报告。假设我们有以下数据库:

+-----------+-----------+----------------+-------------------+-------------------+------------------+
|  Student  | Report ID | StudentMood ID | Exam Cycle Status | Initial Exam Date | Report created a |
+-----------+-----------+----------------+-------------------+-------------------+------------------+
| Student 1 |         1 |              1 | Done              | 01/01/2020        | 02/01/2020       |
| Student 2 |         2 |              2 | Done              | 01/01/2020        | 02/01/2020       |
| Student 1 |         3 |              3 | On Going          | 02/06/2020        | 01/01/2020       |
| Student 2 |         4 |              4 | On Going          | 02/06/2020        | 01/01/2020       |
+-----------+-----------+----------------+-------------------+-------------------+------------------+
很明显,我想要的是t