我有一个基于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
实例放入小部件以更新上下文。 (我也尝试了Wagtailsbefore_edit_page
hook没有成功。)
此信息可用于编辑处理程序,而不是窗口小部件。您可以使用自定义编辑处理程序,一旦知道窗口实例是什么,它就会重新初始化窗口小部件。像这样的东西:
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.page_instance
return context