在Wa尾页面中是否可能使用prefetch_related来检索相关的(父页面,子页面)?

时间:2019-04-05 02:03:48

标签: python django wagtail

我面临的问题是查询数量重复,这使得在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!如何减少数据库调用?是否可以使用预取并选择相关内容?如果是,如何?如果没有,那么增加查询量的解决方案是什么?

1 个答案:

答案 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)