Spec-Zone.ru › Wagtail

Теория

Введение в деревья

Если вы не знакомы с деревьями как абстрактным типом данных, возможно, вам следует ознакомиться с соответствующими концепциями.

Однако, как веб-разработчик, вы, вероятно, уже хорошо понимаете деревья как каталоги файловой системы или пути. Страницы Wagtail могут создавать такую же структуру, так как каждая страница в дереве имеет свой собственный URL-путь, например:

/
    people/
        nien-nunb/
        laura-roslin/
    events/
        captain-picard-day/
        winter-wrap-up/

Интерфейс Wagtail admin использует дерево для организации контента для редактирования, позволяя вам перемещаться вверх и вниз по уровням дерева через меню «Обозреватель». Этот метод организации — хорошая отправная точка для размышлений о собственных моделях Wagtail.

Узлы и листья

Возможно, полезно рассматривать модели, которые вы хотите создать, полученные от Page, как два типа узлов: родительские и листья. Wagtail не предписывает такой подход, но это хорошая отправная точка, если вы не имеете опыта структурирования собственных типов контента.

Узлы

Родительские узлы в дереве Wagtail, вероятно, захотят организовать и отобразить просматриваемый индекс своих потомков. Например, блогу нужен способ отображения списка отдельных записей.

Родительский узел может предоставить собственную функцию, возвращающую объекты его потомков.

class EventPageIndex(Page):
    # ...
    def events(self):
        # Get list of live event pages that are descendants of this page
        events = EventPage.objects.live().descendant_of(self)

        # Filter events list to get ones that are either
        # running now or start in the future
        events = events.filter(date_from__gte=date.today())

        # Order by date
        events = events.order_by('date_from')

        return events

Этот пример гарантирует, что возвращаемые объекты ограничены частями контента, которые имеют смысл, в частности, теми, которые были опубликованы через интерфейс администратора Wagtail (live()) и являются потомками этого узла (descendant_of(self)). Установив свойство класса subpage_types, вы можете указать, какие модели разрешено устанавливать в качестве потомков, а установив свойство класса parent_page_types, вы можете указать, какие модели разрешено устанавливать в качестве родителей этой модели страницы. Wagtail по умолчанию позволит любую модель, производную от Page. В любом случае, для родительской модели разумно предоставить индекс, отфильтрованный для осмысленности.

Листья

Листья — это сами части контента, страница, которую можно использовать, и она может состоять из набора свойств. Лист страницы блога может содержать текст тела и изображение. Лист страницы человека может содержать фотографию, имя и адрес.

Для листа может быть полезно предоставить способ возврата по дереву к родителю, например, в случае навигации по хлебным крошкам. Дерево также может быть достаточно глубоким, чтобы родитель листа не включался в общую навигацию по сайту.

Модель листа может предоставить функцию, которая перемещается по дереву в обратном направлении и возвращает соответствующего предка:

class EventPage(Page):
    # ...
    def event_index(self):
        # Find closest ancestor which is an event index
        return self.get_ancestors().type(EventIndexPage).last()

При определении subpage_types и parent_page_types также будут ограничивать разрешенные родительские модели, которые могут содержать лист. В противном случае Wagtail позволит любые сочетания родителей и листьев связываться в дереве Wagtail. Как и в случае с индексными страницами, важно убедиться, что индекс фактически является ожидаемой моделью, содержащей лист.

Другие отношения

Ваши модели, производные от Page, могут иметь другие взаимосвязи, которые расширяют базовое дерево Wagtail или полностью от него отличаются. Вы можете предоставить функции для навигации между братьями и сестрами, такие как ссылка «Следующая запись» на странице блога (post->post->post). Возможно, имеет смысл взаимосвязывать поддеревья, например, в форуме обсуждения (forum->post->replies). Также может быть уместно пропустить иерархию, так как все объекты определённого класса модели могут взаимосвязываться независимо от своих предков (events = EventPage.objects.all). В основном модели определяют свои взаимосвязи, возможности действительно безграничны.

Анатомия запроса Wagtail

Для того, чтобы выйти за рамки основ определения модели и взаимосвязей, может быть полезно знать, как Wagtail обрабатывает запросы и создаёт ответы. Короче говоря, это происходит примерно так:

  1. Django получает запрос и обрабатывает его через определения маршрутизатора URL Wagtail
  2. Wagtail проверяет имя хоста запроса, чтобы определить, какой Site запись будет обрабатывать этот запрос.
  3. Начиная с корневой страницы этого сайта, Wagtail проходит по дереву страниц, вызывая метод route() и позволяя каждой модели страницы решить, будет ли она обрабатывать запрос сама или передать его дочерней странице.
  4. Страница, ответственная за обработку запроса, возвращает объект RouteResult из route(), который идентифицирует страницу вместе с любыми дополнительными args/kwargs для передачи в serve().
  5. Wagtail вызывает serve(), который создаёт контекст с использованием get_context().
  6. serve() находит шаблон для передачи его с помощью get_template()
  7. Объект ответа возвращается serve() и Django отвечает запросу.

Вы можете применить пользовательское поведение к этому процессу, переопределяя методы класса Page , такие как route() и serve() в собственных моделях. Примеры см. в Рецептах.

Планируемое публикование

Публикование страниц можно запланировать, используя функцию «Установить расписание» в боковой панели «Статус» на странице «Редактировать». Это позволяет вам заранее настроить первоначальное публикование страницы или обновление страницы. Для того, чтобы страницы были опубликованы в запланированное время, необходимо настроить команду управления publish_scheduled.

Основной рабочий процесс следующий:

  • Планирование выполняется путем установки поля «Публикация по состоянию» страницы и нажатия «Опубликовать».
  • Планирование пересмотра страницы, которая сейчас не отображается, означает, что страница будет опубликована, когда придёт запланированное время.
  • Планирование пересмотра страницы, которая уже опубликована, означает, что пересмотр будет опубликован, когда придёт запланированное время.
  • Если у страницы есть запланированный пересмотр, и вы установите другой пересмотр для немедленной публикации (т. е. нажав «Опубликовать» без установки поля «Публикация по состоянию»), запланированный пересмотр будет отменён.
  • Если у страницы есть запланированный пересмотр, и вы запланируете другой пересмотр для публикации (т. е. нажав «Опубликовать» с установленным полем «Публикация по состоянию»), существующий запланированный пересмотр будет отменён, и вместо него будет запланирован новый.

Обратите внимание, что вам необходимо нажать «Опубликовать» после установки поля «Публикация по состоянию», чтобы пересмотр был запланирован. Сохранение черновика пересмотра с установленным полем «Публикация по состоянию» без нажатия «Опубликовать» не запланирует его публикацию.

В представлении «История» для данной страницы будет показано, какой пересмотр запланирован и когда он запланирован. Запланированный пересмотр в списке также предоставит кнопку «Отменить планирование» для его отмены.

В дополнение к планированию публикации страницы, также можно запланировать снятие страницы с публикации, установив поле «Снятие с публикации». Однако, в отличие от публикации, расписание снятия с публикации применяется к экземпляру активной страницы, а не к определённому пересмотру. Это означает, что любые изменения в поле «Снятие с публикации» будут эффективны только после публикации соответствующего пересмотра (т. е. после применения изменений к экземпляру активной страницы). Для иллюстрации:

  • Планирование выполняется путем установки поля «Снятие с публикации» страницы и нажатия «Опубликовать». Если также установлено поле «Публикация по состоянию», то расписание снятия с публикации будет применено только после того, как пересмотр будет опубликован.
  • Представьте активную страницу, которая запланирована для снятия с публикации, например, 14 июня. Затем, в какой-то момент до расписания, предположим, что запланирован новый пересмотр для публикации в дату, которая раньше расписания снятия с публикации, например, 9 июня. Когда новый пересмотр будет опубликован 9 июня, поле «Снятие с публикации», содержащееся в новом пересмотре, заменит существующее расписание снятия с публикации. Это означает:

    • Если новый пересмотр содержит другое поле «Снятие с публикации» (например, 17 июня), новый пересмотр будет опубликован 9 июня, и страница не будет снята с публикации 14 июня, но она будет снята с публикации 17 июня.
    • Если в новом пересмотре поле «Снятие с публикации» не установлено, новый пересмотр будет опубликован 9 июня, и расписание снятия с публикации будет отменено, следовательно, страница не будет снята с публикации.
  • Представьте другую активную страницу, которая запланирована для снятия с публикации, например, 14 июня. Затем, в какой-то момент до расписания, предположим, что запланирован новый пересмотр для публикации в дату, которая позже расписания снятия с публикации, например, 21 июня. Новый пересмотр не вступит в силу до его публикации 21 июня, поэтому страница всё ещё будет снята с публикации 14 июня. Это означает:

    • Если новый пересмотр содержит другое поле «Снятие с публикации» (например, 25 июня), страница будет снята с публикации 14 июня, новый пересмотр будет опубликован 21 июня, и страница будет снова снята с публикации 25 июня.
    • Если в новом пересмотре поле «Снятие с публикации» не установлено, страница будет снята с публикации 14 июня, новый пересмотр будет опубликован 21 июня.

Такой же механизм планирования также применяется к фрагментам с применением DraftStateMixin. Более подробную информацию см. в разделе Сохранение изменений черновика фрагментов.

© 2014-present Torchbox Ltd and individual contributors.
All rights are reserved.
Licensed under the BSD License.
https://docs.wagtail.org/en/stable/reference/pages/theory.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API