Компоновщик маршрутизируемых страниц
Компоновщик RoutablePageMixin предоставляет удобный способ для страницы реагировать на несколько под-URL с разными представлениями. Например, раздел блога на сайте может предоставлять несколько разных типов страниц индекса по URL, таким как /blog/2013/06/, /blog/authors/bob/, /blog/tagged/python/, все обслуживаемые одним экземпляром страницы.
Страница, использующая Page с RoutablePageMixin, существует в дереве страниц как любая другая страница, но пути URL под ней проверяются на соответствие списку шаблонов. Если ни один из шаблонов не соответствует, управление передается подстраницам, как обычно (или, если это не удаётся, генерируется ошибка 404).
По умолчанию существует маршрут для r'^$', который отображает содержимое точно так же, как это сделала бы обычная Page. Это можно переопределить, используя @re_path(r'^$') или @path('') в любом другом методе наследуемого класса.
Установка
Добавьте "wagtail.contrib.routable_page" в свой INSTALLED_APPS:
INSTALLED_APPS = [
...
"wagtail.contrib.routable_page",
]
Основы
Чтобы использовать RoutablePageMixin, вам нужно сделать ваш класс наследником как :class:wagtail.contrib.routable_page.models.RoutablePageMixin и wagtail.models.Page, а затем определить некоторые методы представления и украсить их path или re_path.
Эти методы представлений ведут себя как обычные функции представлений Django и должны возвращать объект HttpResponse; обычно это делается с помощью вызова django.shortcuts.render.
Декораторы path и re_path из wagtail.contrib.routable_page.models.path аналогичны функциям Django django.urls path и re_path. Первый позволяет использовать простые пути и преобразователи, а второй позволяет указывать шаблоны URL в виде регулярных выражений.
Вот пример EventIndexPage с тремя представлениями, предполагая, что где-то определена модель EventPage с полем event_date:
import datetime
from django.http import JsonResponse
from wagtail.fields import RichTextField
from wagtail.models import Page
from wagtail.contrib.routable_page.models import RoutablePageMixin, path
class EventIndexPage(RoutablePageMixin, Page):
# Routable pages can have fields like any other - here we would
# render the intro text on a template with {{ page.intro|richtext }}
intro = RichTextField()
@path('') # will override the default Page serving mechanism
def current_events(self, request):
"""
View function for the current events page
"""
events = EventPage.objects.live().filter(event_date__gte=datetime.date.today())
# NOTE: We can use the RoutablePageMixin.render() method to render
# the page as normal, but with some of the context values overridden
return self.render(request, context_overrides={
'title': "Current events",
'events': events,
})
@path('past/')
def past_events(self, request):
"""
View function for the past events page
"""
events = EventPage.objects.live().filter(event_date__lt=datetime.date.today())
# NOTE: We are overriding the template here, as well as few context values
return self.render(
request,
context_overrides={
'title': "Past events",
'events': events,
},
template="events/event_index_historical.html",
)
# Multiple routes!
@path('year/<int:year>/')
@path('year/current/')
def events_for_year(self, request, year=None):
"""
View function for the events for year page
"""
if year is None:
year = datetime.date.today().year
events = EventPage.objects.live().filter(event_date__year=year)
return self.render(request, context_overrides={
'title': "Events for %d" % year,
'events': events,
})
@re_path(r'^year/(\d+)/count/$')
def count_for_year(self, request, year=None):
"""
View function that returns a simple JSON response that
includes the number of events scheduled for a specific year
"""
events = EventPage.objects.live().filter(event_date__year=year)
# NOTE: The usual template/context rendering process is irrelevant
# here, so we'll just return a HttpResponse directly
return JsonResponse({'count': events.count()})
Отображение других страниц
Другой способ возврата объекта HttpResponse — вызвать метод serve другой страницы. (Вызов собственного метода serve страницы внутри метода представления недействителен, так как метод представления уже вызывается внутри serve, и это создаст циклическое определение).
Например, EventIndexPage можно расширить маршрутом next/, который отображает страницу для следующего события:
@path('next/')
def next_event(self, request):
"""
Display the page for the next event
"""
future_events = EventPage.objects.live().filter(event_date__gt=datetime.date.today())
next_event = future_events.order_by('event_date').first()
return next_event.serve(request)
Обратное преобразование URL-адресов
RoutablePageMixin добавляет метод reverse_subpage() к вашей модели страницы, который вы можете использовать для обратного преобразования URL-адресов. Например:
# The URL name defaults to the view method name.
>>> event_page.reverse_subpage('events_for_year', args=(2015, ))
'year/2015/'
Этот метод возвращает только часть URL внутри страницы. Чтобы получить полный URL, необходимо добавить его к значениям атрибута url или full_url вашей страницы:
>>> event_page.url + event_page.reverse_subpage('events_for_year', args=(2015, ))
'/events/year/2015/'
>>> event_page.full_url + event_page.reverse_subpage('events_for_year', args=(2015, ))
'http://example.com/events/year/2015/'
Изменение имён маршрутов
Имя маршрута по умолчанию равно имени представления. Вы можете переопределить это имя с помощью ключевого аргумента name в @path или re_path:
from wagtail.models import Page
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
class EventPage(RoutablePageMixin, Page):
...
@re_path(r'^year/(\d+)/$', name='year')
def events_for_year(self, request, year):
"""
View function for the events for year page
"""
...
>>> event_page.url + event_page.reverse_subpage('year', args=(2015, ))
'/events/year/2015/'
Класс RoutablePageMixin
Пример:
url = page.url + page.reverse_subpage('events_for_year', kwargs={'year': '2014'})
Тег шаблона routablepageurl
Пример:
{% load wagtailroutablepage_tags %}
{% routablepageurl page "feed" %}
{% routablepageurl page "archive" 2014 08 14 %}
{% routablepageurl page "food" foo="bar" baz="quux" %}
© 2014-present Torchbox Ltd and individual contributors.
All rights are reserved.
Licensed under the BSD License.
https://docs.wagtail.org/en/stable/reference/contrib/routablepage.html