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
相关产品推荐
相关产品推荐

