这一直困扰着我很长时间,我无法找到答案。
我不确定QuerySet是如何缓存的,
但是prefetch_related
被缓存为列表。
如果您想进一步过滤prefetch_related
,
您可以运行新的prefetch_related
查询,也可以在python级别上对其进行过滤。
当运行查询时,以第二种方式(在python级别上过滤)执行它是有意义的。
QuerySet的方法适用于queryset并返回queryset, 但是使用预取缓存是有利的(我想这样做不仅仅是prefetch_related,而是一般的查询集,如果可能的话)。
我可以想到像
这样的东西class Foo(models.Model):
@property
def bars(self):
if hasattr(self, 'bar_set_prefetched'):
return self.bar_set_prefetched
else:
return self.bar_set.all()
class BarQuerySet(QuerySet):
def is_visible(self):
if prefetched: # don't know how to detect
return [bar for bar in self if bar.visible]
return self.filter(is_visible=True)
class Bar(models.Model):
foo = models.ForeignKey(Foo, related_name='bar_set')
visible = models.BooleanField(default=True)
# client code
foos = Foo.boejcts.prefetch_related(
Prefetch(
'bars',
to_attr='bar_set_prefetched'
)
)
for foo in foos:
bars = foo.bars.is_visible() # I want is_visible to use prefetched list instead of running new query
我不确定它是否可行,并且想知道我需要注意的可能的陷阱。