问题
I have a model based on Wagtails Page
model and I am assigning a custom widget to one of the models fields. Is it possible to make the model instance accessible in the widgets HTML-template when rendering the admin view? I need the widget in the admin view to know which ID the SimplePage
has the widget belongs to, i.e. get the value of {{ 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"
I know I can update the context of my widget like so:
# 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
But I can't figure how to get my SimplePage
instance into the widget to update the context. (I also tried Wagtails before_edit_page
hook w/o success.)
回答1:
This information is available to the edit handler, not the widget. You could use a custom edit handler which re-initialises the widget once it knows what the page instance is. Something like this:
class LeafletPanel(FieldPanel):
def on_instance_bound(self):
self.widget = LeafletWidgetWithMedia(page_instance=self.instance)
on_instance_bound()
is called when the panel is bound to a page object. Note that when creating a new page, this will not get called - so you may need some logic in the widget to handle that case.
You then adjust your LeafletWidgetWithMedia
to accept this instance
argument at initalisation, and can pass that into the context from the get_context()
method:
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
来源:https://stackoverflow.com/questions/59894242/wagtail-how-to-pass-model-instance-to-a-widget-and-access-it-in-template