Django 查询:将两个模型与两个字段连接起来

Ale*_*cia 2 python django django-queryset

我有以下型号:

class AcademicRecord(models.Model):
    record_id = models.PositiveIntegerField(unique=True, primary_key=True)
    subjects = models.ManyToManyField(Subject,through='AcademicRecordSubject')
    ...


class AcademicRecordSubject(models.Model):
    academic_record = models.ForeignKey('AcademicRecord')
    subject = models.ForeignKey('Subject')
    language_group = IntegerCharField(max_length=2)
    ...


class SubjectTime(models.Model):
    time_id = models.CharField(max_length=128, unique=True, primary_key=True)
    subject = models.ForeignKey(Subject)
    language_group = IntegerCharField(max_length=2)
    ...


class Subject(models.Model):
    subject_id = models.PositiveIntegerField(unique=True,primary_key=True)
    ...
Run Code Online (Sandbox Code Playgroud)

学术记录有科目列表,每个科目都有语言代码,科目时间有科目和语言代码。

对于给定的AcademicRecord,我怎么能得到相匹配的主题始终与AcademicRecordSubjectsAcademicRecord有?

这是我的方法,但它会产生比需要更多的查询:

# record is the given AcademicRecord
times = []
for record_subject in record.academicrecordsubject_set.all():
    matched_times = SubjectTime.objects.filter(subject=record_subject.subject)
    current_times = matched_times.filter(language_group=record_subject.language_group)
    times.append(current_times)
Run Code Online (Sandbox Code Playgroud)

我想使用 django ORM 而不是原始 SQL 进行查询

SubjectTime语言组也必须与Subject的语言组匹配

Ale*_*cia 6

我明白了,部分感谢@Robert J\xc3\xb8rgensgaard Eng

\n\n

我的问题是如何使用超过 1 个字段进行内部联接,其中F对象随手可得。
\n正确的查询是:

\n\n
SubjectTime.objects.filter(subject__academicrecordsubject__academic_record=record,\n                           subject__academicrecordsubject__language_group=F('language_group'))\n
Run Code Online (Sandbox Code Playgroud)\n


Rob*_*ahl 5

给定一个AcademicRecord实例academic_record,它要么是

SubjectTime.objects.filter(subject__academicrecordsubject_set__academic_record=academic_record)
Run Code Online (Sandbox Code Playgroud)

或者

SubjectTime.objects.filter(subject__academicrecordsubject__academic_record=academic_record)
Run Code Online (Sandbox Code Playgroud)

结果反映了这些 ORM 查询在 SQL 中变成的连接的所有行。为避免重复,只需使用distinct().

现在这会容易得多,如果我有一个 django shell 来测试:)