3

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

4

1 回答 1

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']

(如果您愿意,也可以使用,或者将infilter(lambda m: m.attribute == 'foo', common)的定义包装起来更明确。)commonlist

是其中之一还是重新发出查询在很大程度上取决于所涉及的集合的大小、过滤器的复杂性以及存在的索引。

于 2012-04-09T00:41:15.980 回答