Django:如何获取一个对象的相关集的相关集

时间:2021-04-15 15:09:05

标签: django django-orm

假设我有以下三个相互关联的模型设置:

class Organisation():
    ....

class Job():
    organisation = models.ForeignKey('Organisation', null=True, blank=True, related_name="jobs", on_delete=models.CASCADE)

class Candidate():
    job = models.ForeignKey('Job', related_name='candidates', on_delete=models.CASCADE)

也就是说,每个Organisation都有很多jobs,而每个Job又都有很多candidates

由此,我知道如何使用 jobs 获取与 organisation 相关的所有 organisation.jobs.all()(“作业集”)。

问。 那么将所有这些放在一起 - 我怎样才能获得与 candidates 相关的所有 Organisation

我脑子一片空白……而且我似乎在网上找不到任何用例……有人知道这种连锁关系的 ORM 简写吗?

3 个答案:

答案 0 :(得分:0)

您可以在 Candidate 模型中添加一个新的 FK 字段

class Candidate():
    job = models.ForeignKey('Job', related_name='candidates', on_delete=models.CASCADE)
    organisation = models.ForeignKey('Organisation', null=True, blank=True, 
    related_name="<any_name>", on_delete=models.CASCADE)

答案 1 :(得分:0)

使用organization.jobs.all(),您将获得所有职位的查询,然后您可以遍历它们并为每个职位提取所有候选人。

最短的方法是在组织模型中添加一个方法:

def get_candidates(self):
        return [job.candidates.all() for job in self.jobs.all() if job.candidates.all().exists()]

def prefetch_candidates(self): 
    queryset = self.jobs.all().prefetch_related('candidates') 
    return [q.candidates.all() for q in queryset]

如果有任何候选人,它将为每个工作返回候选人列表,以避免非候选人工作的空查询集。

测试使用预取的查询数量enter image description here

答案 2 :(得分:0)

既然您想要一个 Candidate 实例的 QuerySet,最合乎逻辑的结论是过滤 Candidate。可以使用 __ 在查找中跨越关系:

result = Candidate.objects.filter(job__organisation=some_organisation_instance)

参考Lookups that span relationships [Django docs]