A widget for Wagtail's admin that allows you to create and select related items.
By default, widgets appear similar to other Wagtail elements, but they can be customised to include images and other items.
Items can be created within the selection widget.
After creation, items can be selected from the success message or from the list view.
pip install wagtail-instance-selector
and add 'instance_selector' to INSTALLED_APPS.
If you're using Django 3+, you will need to change Django's iframe security flag in your settings:
X_FRAME_OPTIONS='SAMEORIGIN'fromdjango.dbimportmodelsfrominstance_selector.edit_handlersimportInstanceSelectorPanelclassShop(models.Model):
passclassProduct(models.Model):
shop=models.ForeignKey(Shop, on_delete=models.CASCADE)
panels= [InstanceSelectorPanel("shop")]fromdjango.dbimportmodelsfromwagtail.admin.edit_handlersimportStreamFieldPanelfromwagtail.core.fieldsimportStreamFieldfrominstance_selector.blocksimportInstanceSelectorBlockclassProduct(models.Model):
passclassService(models.Model):
passclassShop(models.Model):
content=StreamField([
("products", InstanceSelectorBlock(target_model="test_app.Product")),
("services", InstanceSelectorBlock(target_model="test_app.Service")),
])
panels= [StreamFieldPanel("content")]To create reusable blocks, you can subclass InstanceSelectorBlock.
frominstance_selector.blocksimportInstanceSelectorBlockclassProductBlock(InstanceSelectorBlock):
def__init__(self, *args, **kwargs):
target_model=kwargs.pop("target_model", "my_app.Product")
super().__init__(target_model=target_model, **kwargs)
classMeta:
icon="image"# ...StreamField([
("products", ProductBlock()),
])fromwagtail.contrib.modeladmin.optionsimportModelAdmin, modeladmin_registerfrominstance_selector.registryimportregistryfrominstance_selector.selectorsimportModelAdminInstanceSelectorfrom .modelsimportMyModel@modeladmin_registerclassMyModelAdmin(ModelAdmin):
model=MyModelclassMyModelInstanceSelector(ModelAdminInstanceSelector):
model_admin=MyModelAdmin()
defget_instance_display_title(self, instance):
ifinstance:
return"some title"defget_instance_display_image_url(self, instance):
ifinstance:
return"/url/to/some/image.jpg"defget_instance_display_image_styles(self, instance):
# The `style` properties set on the <img> element, primarily of use# to work within style+layout patternsifinstance:
return {
'max-width': '165px',
# ...
}
defget_instance_display_markup(self, instance):
# Overriding this method allows you to completely control how the# widget will display the relation to this specific modelreturn"<div> ... </div>"defget_instance_display_template(self):
# The template used by `get_instance_display_markup`return"instance_selector/instance_selector_widget_display.html"defget_instance_selector_url(self):
# The url that the widget will render within a modal. By default, this # is the ModelAdmin"s list viewreturn"/url/to/some/view/"defget_instance_edit_url(self, instance):
# The url that the user can edit the instance on. By default, this is # the ModelAdmin"s edit view ifinstance:
return"/url/to/some/view/"registry.register_instance_selector(MyModel, MyModelInstanceSelector())Note that the ModelAdminInstanceSelector is designed for the common case. If your needs
are more specific, you may find some use in instance_selector.selectors.BaseInstanceSelector.
Largely, this is a rewrite of neon-jungle/wagtailmodelchooser
that focuses on reusing the functionality in the ModelAdmins. We had started a large build using wagtailmodelchooser
heavily, but quickly ran into UI problems when users needed to filter the objects or create them inline. After
neon-jungle/wagtailmodelchooser#11 received little
response, the decision was made to piece together parts from the ecosystem and replicate the flexibility of
django's raw_id_fields, while preserving the polish in Wagtail's UI.
Much of this library was built atop of the work of others, specifically:
- https://github.com/neon-jungle/wagtailmodelchooser
- https://github.com/springload/wagtailmodelchoosers
- https://github.com/Naeka/wagtailmodelchooser
pip install -r requirements.txt
python runtests.py
pip install -r requirements.txt
black .



