我面临的问题是查询数量重复,这使得在Page模型上使用get_parent()或get_children()时应用程序变慢。如果父页面具有模板中使用的图像文件,则该值也会增加。
所以我正在寻找一种方法来预取相关页面而不建立前键关系。
让我们说我有一个TvSeries页面模型和一个插曲页面模型:
class TvSeries(Page):
name = models.CharField()
producer = models.CharField()
subpage_types = ['Episode']
class Episode(Page):
title = models.CharField()
number = models.CharField()
parent_page_types = ['TvSeries']
查询情节模型时需要预取TvSeries!如何减少数据库调用?是否可以使用预取并选择相关内容?如果是,如何?如果没有,那么增加查询量的解决方案是什么?
答案 0 :(得分:1)
prefetch_related
不能用于父/子页面关系,因为它们不使用标准的Django ForeignKey
关系-而是Wagtail(和Treebeard)使用path
字段来表示树的位置。这样就可以执行用ForeignKey
无法有效完成的查询,例如获取页面的所有后代(在任何深度)。
请注意,prefetch_related
不是“免费的”-它将为遵循的每个关系生成一个额外的查询。 Treebeard的查询方法通常在效率上等于或优于此方法-例如:
series = TvSeries.objects.get(id=123)
episodes = series.get_children()
将在两个查询中获取TvSeries
及其所有情节,就像一个(假设的)prefetch_related
表达式一样:
# fake code, will not work...
series = TvSeries.objects.filter(id=123).prefetch_related('child_pages')
但是,get_children
的一个问题是它只会返回基本的Page
实例,因此需要进一步的查询才能从Episode
检索特定字段。您可以使用child_of
来避免这种情况:
series = TvSeries.objects.get(id=123)
episodes = Episode.objects.child_of(series)