如何检查数据透视表行存在?求物品供应商全存在的简洁验证方法
优化方案:利用Django ORM减少循环与数据库查询
你的需求是检查是否存在某个物品,其所有给定供应商都在ItemProviderConn关联表中。原代码的嵌套循环会产生大量数据库查询,效率较低,这里提供几种更简洁高效的实现方式:
方法1:基于关联表的分组统计(适用于items是列表的情况)
# 先提取所有供应商的ID(去重避免重复统计) provider_ids = list({p.pk for p in providers}) provider_count = len(provider_ids) if provider_count == 0: return True # 如果没有指定供应商,默认符合条件 # 找出所有关联了全部指定供应商的物品ID valid_item_ids = ( ItemProviderConn.objects.filter(provider_id__in=provider_ids) .values("item_id") .annotate(matched_providers=Count("provider_id", distinct=True)) .filter(matched_providers=provider_count) .values_list("item_id", flat=True) ) # 检查输入的物品列表中是否有符合条件的项 return any(item.pk in valid_item_ids for item in items)
方法2:基于物品模型的关联统计(适用于items是QuerySet的情况)
如果items是Django的QuerySet而非普通列表,可以直接通过物品模型的关联字段查询,效率更高:
provider_ids = list({p.pk for p in providers}) provider_count = len(provider_ids) if provider_count == 0: return True # 直接判断是否存在符合条件的物品 return ( items.annotate( matched_providers=Count("itemproviderconn__provider_id", distinct=True) ) .filter(matched_providers=provider_count) .exists() )
核心优化点:
- 减少数据库查询次数:原代码每遍历一个供应商就发起一次查询,优化后仅需1-2次数据库操作,数据量越大优势越明显
- 利用数据库统计能力:通过
annotate+Count让数据库完成统计逻辑,比Python循环更高效 - 去重处理:用集合处理供应商ID,避免重复供应商导致统计错误
内容的提问来源于stack exchange,提问作者JanDuda322
相关产品推荐
相关产品推荐

