You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Django ORM对无关联模型执行左外连接查询?

Django ORM实现无外键模型的差集查询

问题描述

现有两个无外键关联的Django模型:

class One(models.Model):
    name = models.CharField(max_length=300, unique=True)


class Two(models.Model):
    name = models.CharField(max_length=300, unique=True)

需要找出name未出现在Two表中的One实例,对应的目标SQL是:

select app_one.name
from app_one left join app_two on app_one.name = app_two.name
where app_two.name is null
group by 1;

不想用那种“查询One所有name再用IN判断不在Two里”的方案(扩展性太差),询问是否可以通过Django ORM实现该查询,还是必须编写原生SQL?

解决方案

当然可以用Django ORM实现,不用写原生SQL。有两种常用方案,都能生成和目标SQL等价的高效查询,不会出现内存占用过高的问题:

方案一:使用Subquery+OuterRef

from django.db.models import OuterRef, Subquery

# 构造子查询,匹配当前One的name是否存在于Two中
two_name_subquery = Two.objects.filter(name=OuterRef('name')).values('name')
# 筛选One中不在子查询结果里的实例
result = One.objects.exclude(name__in=Subquery(two_name_subquery))

这个写法生成的SQL逻辑和你提供的左连接完全一致,不会把所有name加载到内存,适合大数据量场景。

方案二:使用Exists子查询

from django.db.models import Exists, OuterRef

# 判断当前One的name是否存在于Two中的存在性子查询
name_exists_in_two = Exists(Two.objects.filter(name=OuterRef('name')))
# 筛选不存在的实例
result = One.objects.filter(not name_exists_in_two)

这种写法更直观,生成的SQL会用NOT EXISTS子句,性能和左连接方案相当,同样具备良好的扩展性。

两种方案都避开了你提到的扩展性差的IN查询问题,完全满足需求。

内容的提问来源于stack exchange,提问作者dfrankow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 12:43:27