Wagtail:如何将模型实例传递给小部件并在模板中访问它
Wagtail: How to pass model instance to a widget and access it in template
我有一个基于 Wagtails Page
模型的模型,我正在为其中一个模型字段分配一个自定义小部件。在呈现管理视图时,是否可以使模型实例在小部件 HTML 模板中可访问?我需要管理视图中的小部件来知道 SimplePage
的小部件属于哪个 ID,即获取 {{ 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 w/o 成功。)
此信息可用于编辑处理程序,而不是小部件。您可以使用自定义编辑处理程序,一旦它知道页面实例是什么,它就会重新初始化小部件。像这样:
class LeafletPanel(FieldPanel):
def on_instance_bound(self):
self.widget = LeafletWidgetWithMedia(page_instance=self.instance)
on_instance_bound()
在面板绑定到页面对象时调用。请注意,在创建新页面时,不会调用它 - 因此您可能需要在小部件中使用一些逻辑来处理这种情况。
然后您调整 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.instance
return context
我有一个基于 Wagtails Page
模型的模型,我正在为其中一个模型字段分配一个自定义小部件。在呈现管理视图时,是否可以使模型实例在小部件 HTML 模板中可访问?我需要管理视图中的小部件来知道 SimplePage
的小部件属于哪个 ID,即获取 {{ 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 w/o 成功。)
此信息可用于编辑处理程序,而不是小部件。您可以使用自定义编辑处理程序,一旦它知道页面实例是什么,它就会重新初始化小部件。像这样:
class LeafletPanel(FieldPanel):
def on_instance_bound(self):
self.widget = LeafletWidgetWithMedia(page_instance=self.instance)
on_instance_bound()
在面板绑定到页面对象时调用。请注意,在创建新页面时,不会调用它 - 因此您可能需要在小部件中使用一些逻辑来处理这种情况。
然后您调整 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.instance
return context