我已经缓存了一个常见的查询集,我想根据具体情况根据不同的字段进行过滤。我想知道是否通过过滤一个评估的查询集,如果我失去了首先缓存它的优势; Django是否只是从头创建另一个查询集,它是创建缓存查询集和我之后应用的过滤器所涉及的查询集的集合?
答案 0 :(得分:6)
是的,结果被抛弃了。
您可以从来源看到此消息:filter()
调用_filter_or_exclude()
,调用_clone()
然后添加到其查询中。您可以看到,_clone
未设置_result_cache
属性。
一般来说,保持共同结果可能会做些什么并不是很清楚。如果它是一个带有小结果集的复杂查询,它可以被替换为只发出检查主键是你找到的结果之一的SQL,但这并不总是更高效,在某些情况下它会混淆地混淆语义(如果数据库以影响查询的方式发生变化,则会在缓存时和执行额外过滤之间的时间内发生变化。)
如果要强制手动保存ID的这种行为,可以这样做:
pks = SomeObject.objects.filter(...).values_list('pk', flat=True)
some_of_them = SomeObject.objects.filter(pk_in=pks).filter(...)
others = SomeObject.objects.filter(pk_in=pks).filter(...)
您当然也可以在Python中进行过滤,例如由
common = SomeObject.objects.filter(...)
some_of_them = [m for m in common if m.attribute == 'foo']
others = [m for m in common if m.other_attribute == 'bar']
(如果您愿意,也可以使用filter(lambda m: m.attribute == 'foo', common)
,或者将common
中的list
定义更明确。)
其中一个或重新发布查询在很大程度上取决于所涉及的集合的大小,过滤器的复杂性以及存在的索引。