从没有外键的两个模型的 JOIN 中检索值(Django)
Posted
技术标签:
【中文标题】从没有外键的两个模型的 JOIN 中检索值(Django)【英文标题】:Retrieve values from the JOIN of two models without foreign key (Django) 【发布时间】:2021-01-07 11:10:46 【问题描述】:我想检索与两个不同模型相关的两列的值(没有外键)。在 SQL 中,我会这样写:
SELECT employees.name, companies.name
FROM employees
JOIN companies
ON companies.location=employees.location;
假设这两个模型分别称为Employee
和Company
。它们没有共同的外键,我不能更改模型。
我怎样才能在 Django 中拥有相同的功能?我是否必须编写原始 SQL 查询?
【问题讨论】:
你能过滤位置吗?location
只是一个常规列,在我的情况下它不是 Django 模型。
你看过这个吗?***.com/questions/39291372/…
@BriseBalloches 谢谢,我能够使用您链接的答案中的信息来制定解决方案。
【参考方案1】:
我将添加答案作为其他用户的参考,因为在 cmets 中链接的类似问题不是很详细。
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')
这会创建对Employee
对象的location
属性的引用。之所以称为 OuterRef,是因为它指的是在子查询(即调用子查询)之外使用的模型。
2.
Subquery(Company.objects.filter(location=OuterRef('location')).values('name'))
子查询返回location
与员工相同的所有公司的名称。
3.
Employee.objects.annotate(
company_name=Subquery(...)
)
这基本上是用一个名为company_name
的新字段来注释“全局”查询返回的Employee
对象。此字段存储来自 (2) 的子查询的结果。
生成的 SQL 查询将如下所示:
SELECT employees.name,
(SELECT companies.name
FROM companies
WHERE companies.location = employees.location) AS company_name
FROM employees
(我简化了一些由 Django ORM 产生的混乱)。
注意
请务必注意,这将使用 子查询(而不是 joins)。在某些情况下,这可能会影响性能。
【讨论】:
【参考方案2】:对于此类请求,您应该编写原始 SQL...
但是您确定这里实际上不需要外键吗?
【讨论】:
我无法更改模型,因此在我的情况下不能选择外键。另外,我想将我的问题集中在我当前设置中实现与我发布的 SQL 查询相同的结果的可能性(或不)上。如果 Django 在没有原始 SQL 查询的情况下无法做到这一点,我想这就是答案 :)以上是关于从没有外键的两个模型的 JOIN 中检索值(Django)的主要内容,如果未能解决你的问题,请参考以下文章