查询反向外键是否为惰性加载?代码效率优化疑问
关于你的代码效率问题解答
你的代码逻辑是高效的,any()会短路求值——也就是说只要生成器返回第一个True,any()就会立刻停止后续所有检查,不会遍历完所有产品类型。
为什么这个逻辑高效?
你在生成器里每次yield的是exists()的结果,这是Django ORM提供的轻量级查询:
- 它只会检查对应产品集合中是否存在符合条件的记录,不会拉取所有数据到内存;
- 数据库层面执行的是
EXISTS语句,只需要找到第一条匹配的记录就会终止查询,性能非常好。
代码执行流程
当any()遍历生成器时,会依次对每个产品集合执行exists()查询:
- 如果第一个产品集合存在符合条件的记录,
exists()返回True,any()直接返回True,后面的产品集合都不会再触发数据库查询; - 只有当前面所有产品集合的
exists()都返回False时,才会继续检查下一个。
代码优化建议
可以把重复的过滤逻辑抽出来,避免冗余的模型名称判断,让代码更简洁可读:
def has_connected_product(self): def check_product_set(product_set): # 根据模型选择对应的过滤字段 if product_set.model.__name__ == 'ShopifyProduct': filter_args = {'shopify_id__isnull': False, 'shopify_id__ne': 0} else: filter_args = {'source_id__isnull': False, 'source_id__ne': 0} return product_set.filter(**filter_args).exists() product_sets = [ self.user.shopifyproduct_set, self.user.commercehqproduct_set, self.user.wooproduct_set, self.user.ebayproduct_set, self.user.fbproduct_set, self.user.googleproduct_set, self.user.gearbubbleproduct_set, self.user.groovekartproduct_set, self.user.bigcommerceproduct_set, ] return any(check_product_set(ps) for ps in product_sets)
这里用生成器表达式直接传给any(),比嵌套函数更简洁,同时保留了短路求值的核心优势;另外用filter()代替两次exclude(),逻辑等价但可读性更强。
内容的提问来源于stack exchange,提问作者Sasha S
相关产品推荐
相关产品推荐

