Django 1.10优化OR查询的Pythonic写法咨询
优化Django ORM查询:减少重复并正确处理NULL用户
嘿,这个场景我太熟悉了!直接把None塞进user__in列表确实行不通——因为Django的__in会生成SQL的IN (...)语句,但SQL里NULL是不能用IN来匹配的,得用IS NULL才行。不过咱们可以通过抽离重复条件+拆分用户匹配逻辑的方式,把这段代码改得更简洁、更Pythonic。
第一步:抽离重复的通用过滤条件
你原来的两个Q对象里,status_id__in和revision=0是完全重复的,咱们可以把这部分单独拎出来,用字典存储,避免重复书写:
# 把重复的过滤条件抽成字典,复用性更强 common_filters = { 'status_id__in': [Status.Open['id'], Status.Empty['id']], 'revision': 0 }
第二步:正确处理用户的OR条件
针对用户的两种情况(在指定列表里,或者为None),咱们分开写Q对象再用|组合:
# 先获取要匹配的用户列表 user_list = [cache.user for cache in caches] # 组合用户条件:要么在列表里,要么是NULL user_conditions = Q(user__in=user_list) | Q(user__isnull=True)
如果你的caches是Django QuerySet的话,更推荐用values_list直接从数据库层面获取用户,比循环列表推导式更高效:
# 假设caches是QuerySet,flat=True返回一维列表 user_list = caches.values_list('user', flat=True)
第三步:组合所有条件
最后把用户条件和通用条件组合起来,传给filter:
filters_qs = filters_qs.filter(user_conditions, **common_filters)
这样重构后的代码,不仅去掉了重复的逻辑,而且清晰区分了不同的过滤维度,读起来更舒服,也符合Python的DRY(Don't Repeat Yourself)原则。
内容的提问来源于stack exchange,提问作者user2880391
相关产品推荐
相关产品推荐

