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

Django ORM中无外键模型按ProductID实现INNER JOIN关联查询的方法

方案1:使用Subquery实现关联查询(Django 1.11及以上版本支持,官方推荐)

这种写法完全符合Django ORM规范,不需要手动写原生SQL片段,避免SQL注入风险:
首先导入依赖:
from django.db.models import OuterRef, Subquery
然后执行查询:

# 构造子查询:匹配相同ProductID的Product条目的Url
product_url_subq = Product.objects.filter(ProductID=OuterRef('ProductID')).values('Url')[:1]
# 给PriceHistory注解关联的Url,排除无匹配的条目(等效INNER JOIN逻辑)
url_list = PriceHistory.objects.annotate(
    product_url=Subquery(product_url_subq)
).exclude(
    product_url__isnull=True
).values_list('product_url', flat=True)

最终url_list就是你要的所有关联匹配的Url集合。


方案2:使用extra自定义关联逻辑(写法简单,适合快速实现)

这种写法生成的SQL和你给出的原生SQL几乎完全一致,注意如果表名是带应用前缀的,需要替换tables和where里的表名:

url_list = PriceHistory.objects.extra(
    select={'product_url': 'product.Url'},
    tables=['product'],
    where=['pricehistory.ProductID = product.ProductID']
).values_list('product_url', flat=True)

注意:Django默认会给模型生成应用名_小写模型名格式的表名,比如你的模型放在名为goods的应用下,表名就需要改为goods_product和goods_pricehistory。


方案3:Python层面匹配(仅适合小数据量场景)

如果两个表的数据量都不大(万级以下),可以直接在内存中做映射匹配,不需要走数据库联表:

# 构造ProductID到Url的映射字典
product_mapping = {item.ProductID: item.Url for item in Product.objects.all()}
# 过滤出有匹配ProductID的PriceHistory条目,提取对应的Url
url_list = [product_mapping[item.ProductID] for item in PriceHistory.objects.filter(ProductID__in=product_mapping.keys())]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 12:06:07