Поскольку у меня когда-либо будет скрыт только один ребенок page
, я создал пару миксинов, чтобы "скрыть" страницу.Возьмем следующую иерархию:
HomePage --> Destination Index --> Destinations
HomePage
будет иметь этот миксин:
class ConcealedChildMixin(Page):
"""
A mixin to provide functionality for a child page to conceal it's
own URL, e.g. `/birmingham` instead of `/destination/birmingham`.
"""
concealed_child = models.ForeignKey(
Page,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='concealed_parent',
help_text="Allow one child the ability to conceal it's own URL.",
)
content_panels = Page.content_panels + [
FieldPanel('concealed_child')
]
class Meta:
abstract = True
def route(self, request, path_components):
try:
return super().route(request, path_components)
except Http404:
if path_components:
subpage = self.specific.concealed_child
if subpage and subpage.live:
return subpage.specific.route(
request, path_components
)
raise Http404
И Destinations
будет иметь этот миксин:
class ConcealedURLMixin:
"""
A mixin to provide functionality for a page to generate the correct
URLs if it's parent is concealed.
"""
def set_url_path(self, parent):
"""
Overridden to remove the concealed page from the URL.
"""
if parent.concealed_parent.exists():
self.url_path = (
'/'.join(
[parent.url_path[: len(parent.slug) - 2], self.slug]
)
+ '/'
)
else:
self.url_path = super().set_url_path(parent)
return self.url_path