Django查询:用两个字段连接两个模型

3 投票
2 回答
6615 浏览
提问于 2025-04-18 09:02

我有以下这些模型:

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)
    ...

学术记录里有一系列科目,每个科目都有一个语言代码,而科目时间则有科目和语言代码。

给定一个AcademicRecord,我该如何获取与这个AcademicRecord中包含的AcademicRecordSubjects相匹配的科目时间呢?

这是我的方法,但它查询的次数比需要的还要多:

# 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)

我想用django的ORM来进行查询,而不是用原始的SQL语句。

SubjectTime的语言组必须与Subject的语言组相匹配。

2 个回答

5

给定一个叫做 academic_recordAcademicRecord 实例,它可能是

SubjectTime.objects.filter(subject__academicrecordsubject_set__academic_record=academic_record)

或者

SubjectTime.objects.filter(subject__academicrecordsubject__academic_record=academic_record)

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

如果我有一个 django shell 来测试,那就简单多了 :)

6

我明白了,这多亏了@Robert Jørgensgaard Eng的帮助。

我遇到的问题是如何使用多个字段进行内连接,这时候F对象就派上用场了。
正确的查询语句是:

SubjectTime.objects.filter(subject__academicrecordsubject__academic_record=record,
                           subject__academicrecordsubject__language_group=F('language_group'))

撰写回答