Возможно ли использовать prefetch_related для извлечения связанных (родительские, дочерние страницы) страниц в Wagtail Pages? - PullRequest
2 голосов
/ 05 апреля 2019

Проблема, с которой я сталкиваюсь, заключается в дублировании количества запросов, что замедляет работу приложения при использовании 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 Ответ

1 голос
/ 05 апреля 2019

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)
...