ManyToMany Relationships in Wagtail

I'm loving Wagtail so far. There does seem to be one catch though. It doesn't handle ManyToMany relationships particularly well in the admin.

In Wagtail's defence, the problem is caused by Model Cluster which Wagtail relies heavily on itself.

I am in the position of wanting to link two Post-types together which it took me a while to figure out how to do. The standard Django method of models.ManyToMany('self') just doesn't work in Wagtail and you get the dreaded ValueError "<BlogPage: foo>" needs to have a value for field "blogpage" before this many-to-many relationship can be used. error.

I've been finding the Tivix invaluable for Wagtail tips but in this case I wanted to do something a bit different. Tivix also points to the wagtaildemo which is proving illuminating albeit hard work.

In the end I used a combination of InlinePanel and a ParentalKey to create a RelatedPost class that could link to another content item:

from modelcluster.fields import ParentalKey
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.models import Orderable
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel
from wagtail.wagtailadmin.edit_handlers import InlinePanel


class ContentPage(Page):
    summary = RichTextField(blank=True)
    body = RichTextField(blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('summary'),
        FieldPanel('body', classname="full"),
        InlinePanel('related_content_page', label="Related Content")
    ]


class RelatedPost(Orderable):
    post = ParentalKey(
        'ContentPage',
        related_name='related_content_page'
    )
    page = models.ForeignKey(
        'ContentPage',
        related_name="+"
    )
    panels = [
        FieldPanel('page')
    ]

So far it's working quite well for me and presumably would work with any other Model you might like to link to another.