Как передать "self" или Page.id в пользовательскую панель администратора в Wagtail CMS?
В более общем смысле я хочу добавить пользовательскую админку Panel
для списка некоторого связанного контента. Для поиска этого связанного содержимого мне нужно передать текущий экземпляр модели или, по крайней мере, ее ID в эту панель. Как я могу это сделать внутри этих списков, в которых отмечены эти панели администратора?
Вот мой конкретный пример ArtistPage
. В редакторе я хотел бы добавить панель для списка WorkPages
, которые связаны с этим ArtistPage
:
from wagtail.models import Page
class ArtistPage(Page):
# ...
content_panels = [
# ...
ListWorksPanel(artist=self), # This doesn’t work
]
Сама панель определяется так, в основном копируется из HelpPanel
:
from wagtail.admin.panels import Panel
class ListWorksPanel(Panel):
def __init__(self, artist="", template="admin/list_works_panel.html", **kwargs,):
super().__init__(**kwargs)
self.artist = artist
self.template = template
def clone_kwargs(self):
kwargs = super().clone_kwargs()
del kwargs["help_text"]
kwargs.update(
artist=self.artist,
template=self.template,
)
return kwargs
class BoundPanel(Panel.BoundPanel):
def __init__(self, panel, instance, request, form):
super().__init__(panel, instance, request, form)
self.template_name = self.panel.template
self.artist = self.panel.artist
Это скорее общий вопрос по Python, я думаю. Я знаю, как передавать "self" в функциях. Но как это работает здесь с этим классом как элементом списка? Я полагаю, что метод __init__()
ArtistPage
- это то, что нужно, но я не могу понять, как именно.
Каким питоническим способом можно передать "self" другому классу?
Экземпляр ArtistPage передается в BoundPanel.__init__
как аргумент ключевого слова instance
. Весь код, имеющий дело с отдельной ArtistPage, должен быть написан внутри класса BoundPanel
.
Когда вы пишете ListWorksPanel()
как часть определения content_panels
, вы создаете экземпляр ListWorksPanel
, который затем становится частью определения класса ArtistPage . В этот момент в коде не существует реального экземпляра ArtistPage, поэтому нет self
, на который можно было бы сослаться. Фактически, существует единственный объект ListWorksPanel
, общий для всех экземпляров ArtistPage, которые когда-либо будут созданы.
Когда приходит время отобразить форму редактирования для отдельной страницы, Wagtail вызывает get_bound_panel
объект ListWorksPanel, передавая экземпляр страницы вместе с объектами формы и запроса. ( Полный процесс объясняется здесь.) Это возвращает экземпляр BoundPanel, который является компонентом шаблона, выполняющим окончательный рендеринг. В этом случае вы, вероятно, захотите определить метод get_context_data на BoundPanel, который делает что-то вроде context['works'] = self.instance.works.all()
- это сделает переменную works
доступной на шаблоне.