use*_*721 3 django django-queryset
我已经缓存了一个常见的查询集,我想根据具体情况根据不同的字段进行过滤.我想知道是否通过过滤一个评估的查询集,如果我失去了首先缓存它的优势; Django是否只是从头创建另一个查询集,它是创建缓存查询集和我之后应用的过滤器所涉及的查询集的集合?
是的,结果被抛弃了.
您可以从源代码中看到这一点: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(...)
Run Code Online (Sandbox Code Playgroud)
您当然也可以在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']
Run Code Online (Sandbox Code Playgroud)
(filter(lambda m: m.attribute == 'foo', common)如果您愿意,也可以使用,或者将commonin 的定义包装list为更明确.)
无论是其中之一还是重新发布查询都很大程度上取决于所涉及的集合的大小,过滤器的复杂性以及存在的索引.