Трясогузка: как передать экземпляр модели в виджет и получить к нему доступ в шаблоне - PullRequest
1 голос
/ 24 января 2020

У меня есть модель на основе модели Wagtails Page, и я назначаю собственный виджет одному из полей моделей. Можно ли сделать экземпляр модели доступным в шаблонах HTML при отображении представления администратора? Мне нужен виджет в представлении администратора, чтобы знать, к какому идентификатору SimplePage принадлежит виджет, т.е. получить значение {{ page.id }}.

# models.py
class SimplePage(Page):

    name = RichTextField(blank=True)
    geom = PointField()

    content_panels = Page.content_panels + [
        FieldPanel("name"),
        FieldPanel("geom", widget=LeafletWidgetWithMedia()),
    ] 
# widgets.py
class LeafletWidgetWithMedia(LeafletWidget):
    include_media = True
    template_name = "admin/widget.html"

Я знаю, что могу обновить контекст моего виджета примерно так:

# widgets.py
# ...
    def get_context(self, name, value, attrs):
        value = None if value in validators.EMPTY_VALUES else value
        context = super(LeafletWidget, self).get_context(name, value, attrs)
        context.update(self._get_attrs(name, attrs))
        return context

Но я не могу понять, как вставить свой экземпляр SimplePage в виджет для обновления контекста. (Я также попробовал Wagtails before_edit_page hook без успеха.)

1 Ответ

1 голос
/ 25 января 2020

Эта информация доступна обработчику редактирования, а не виджету. Вы можете использовать пользовательский обработчик редактирования, который повторно инициализирует виджет, как только он узнает, что такое экземпляр страницы. Примерно так:

class LeafletPanel(FieldPanel):

    def on_instance_bound(self):
        self.widget = LeafletWidgetWithMedia(page_instance=self.instance)

on_instance_bound() вызывается, когда панель привязана к объекту страницы. Обратите внимание, что при создании новой страницы это не будет вызываться, поэтому вам может потребоваться логика c в виджете для обработки этого случая.

Затем вы настраиваете LeafletWidgetWithMedia для принятия этого аргумента instance при инициализации и можете передать его в контекст из метода get_context():

class LeafletWidgetWithMedia(LeafletWidget):

    def __init__(self, *args, **kwargs):
        self.instance = kwargs.pop('page_instance', None)
        super().__init__(*args, **kwargs)

    def get_context(self, name, value, attrs):
        # ...
        context['page_instance'] = self.page_instance
        return context
...