Django如何过滤评估的查询集?

时间:2012-04-09 00:21:51

标签: django django-queryset

我已经缓存了一个常见的查询集,我想根据具体情况根据不同的字段进行过滤。我想知道是否通过过滤一个评估的查询集,如果我失去了首先缓存它的优势; Django是否只是从头创建另一个查询集,它是创建缓存查询集和我之后应用的过滤器所涉及的查询集的集合?

1 个答案:

答案 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定义更明确。)

其中一个或重新发布查询在很大程度上取决于所涉及的集合的大小,过滤器的复杂性以及存在的索引。