How to add an InlinePanel for related objects?

203 views
Skip to first unread message

Martin Brochhaus

unread,
Oct 19, 2018, 5:21:21 AM10/19/18
to Wagtail support
Hi everyone,

I have trouble with this probably simple task:

Let's say I have a "BlogPage(Page)" model.

I have defined this on the model:

```
general_panels = [
        MultiFieldPanel(
            [
                InlinePanel('related_products'),
            ],
            heading='Related Products',
            classname='collapsible collapsed'),
]
```

Furthermore, I defined this:

```
class BlogPageProduct(models.Model):
    product = models.ForeignKey(
        'products.Product', related_name='+', verbose_name=_('Product'), on_delete=models.CASCADE)
    page = ParentalKey('BlogPage', related_name='related_products')
```

This gets me close to my desired result. In the Wagtail admin I can see the collapsed section "Related Products" and I can press the "Add" button. The problem is, we have thousands of products and the drop down list that contains all the products is so big, it would crash my browser.

So I am wondering if there is some way to get a popup window that lets me search for a product and then select the one that I want, similar to how that magnifying glass in the normal Django admin works, when we use raw_id_fields.

Best regards
Martin

Matthew Westcott

unread,
Oct 19, 2018, 7:18:38 AM10/19/18
to wag...@googlegroups.com
Hi Martin,

I'd suggest registering your Product model as a snippet <http://docs.wagtail.io/en/v2.2.2/topics/snippets.html#snippet-models>, and then using a SnippetChooserPanel, which provides a popup chooser interface similar to the one in the Django admin:

http://docs.wagtail.io/en/v2.2.2/topics/snippets.html#binding-pages-to-snippets

If defining Product as a snippet isn't possible (for example, it's part of a third-party app), there are a couple of add-on packages that provide a pop-up chooser interface for arbitrary models:

https://github.com/springload/wagtailmodelchoosers
https://github.com/takeflight/wagtailmodelchooser

Cheers,
- Matt
> --
> You received this message because you are subscribed to the Google Groups "Wagtail support" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to wagtail+u...@googlegroups.com.
> To post to this group, send email to wag...@googlegroups.com.
> Visit this group at https://groups.google.com/group/wagtail.
> To view this discussion on the web, visit https://groups.google.com/d/msgid/wagtail/2a5ded6a-5829-457e-a3b0-32fd99061f44%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Martin Brochhaus

unread,
Oct 21, 2018, 11:58:07 PM10/21/18
to Wagtail support
Hi Matt,

thank you so much for your reply! This was exactly what I needed and I got it working now.

I also had to discover http://docs.wagtail.io/en/v2.2.2/topics/search/indexing.html#wagtailsearch-indexing-models so that I can search for products while adding them as related products to a blog page.

Cheers,
Martin

James Farris

unread,
Oct 23, 2018, 3:23:24 PM10/23/18
to Wagtail support
I would say the thing you lose with Snippets is revision history and other Page class related options.  If you don't care about revisions or Page related options with this particular content, then snippets are an easy way to go.

If you would like revision history and the added options then you would create a page class that becomes a sub-class of the parent page.  Then you would use an InlineChooser to select the Page you want to be a child page.  It's a great setup.  Here is sample code I used to create this very thing in a project I built at work.  Basically the "Donor" page content gets looped through in the template on the "SharingTheLightPageIndex" page.  With this setup you get revision history on the "snippets"

class SharingTheLightPageIndex(Page):

content_panels = Page.content_panels + [
InlinePanel(
'donors',
label='Donors',
),
]

parent_page_types = ['HomePage']
subpage_types = ['Donor']


class Donor(Page):
# Fields removed for simplicity

# WagTail admin panels
content_panels = Page.content_panels + [
]

# prevents this page type from being added to other page types that aren't listed below
parent_page_types = ['SharingTheLightPageIndex']
subpage_types = []


# Intermediary classes for Donor Sub-Page
# --------------------- #
class DonorInstance(models.Model):
donor = models.ForeignKey(
'Donor',
null=True,
on_delete=models.SET_NULL,
related_name='+',
)
panels = [
PageChooserPanel('donor', 'home.Donor'),
]


class DonorIndexFeaturedDonors(Orderable, DonorInstance):
"""Orderable ParentalKey go-between for FeaturedDonor and
DonorIndex."""
page = ParentalKey(
'SharingTheLightPageIndex',
on_delete=models.CASCADE,
related_name='donors',
)
Reply all
Reply to author
Forward
0 new messages