首页 > 解决方案 > 从没有外键的两个模型的 JOIN 中检索值(Django)

问题描述

我想检索与两个不同模型(没有外键)相关的两列的值。在 SQL 中,我会这样写:

SELECT employees.name, companies.name
FROM employees
JOIN companies
ON companies.location=employees.location;

假设这两个模型被称为EmployeeCompany。它们没有共同的外键,我也不能更改模型。

我怎样才能在 Django 中拥有相同的功能?我是否必须编写原始 SQL 查询?

标签: sqldjangojoin

解决方案


我将添加答案作为其他用户的未来参考,因为评论中链接的类似问题不是很详细。

from django.db.models import Subquery, OuterRef

Employee.objects.annotate(
    company_name=Subquery(
        Company.objects.filter(location=OuterRef('location')).values('name')
    )
).values_list('name', 'company_name')

解释

将其分成几部分(从内到外):

1.

OuterRef('location')

这将创建location对对象属性的引用Employee。之所以称为Outer Ref,是因为它指的是在子查询(调用子查询)之外使用的模型。

2.

Subquery(Company.objects.filter(location=OuterRef('location')).values('name'))

子查询返回与location员工相同的所有公司的名称。

3.

Employee.objects.annotate(
    company_name=Subquery(...)
)

这基本上是Employee用一个名为company_name. 此字段存储来自 (2) 的子查询的结果。

生成的 SQL 查询将如下所示:

SELECT employees.name,
  (SELECT companies.name
   FROM companies
   WHERE companies.location = employees.location) AS company_name
FROM employees

(我简化了 Django ORM 产生的一些混乱)。

笔记

重要的是要注意这将使用子查询(而不是连接)。在某些情况下,这可能会影响性能。


推荐阅读