PageChooserBlock questions

479 views
Skip to first unread message

Nick Barreto

unread,
Jan 8, 2016, 7:01:22 AM1/8/16
to Wagtail support
Hi There everyone,

I had been using a regular Foreign Key relation to setup some relationships of many-to one between some pages (between a book page and its author), but I actually need it to be a bit more complex, as there may be more than one author to a book.

It seemed to be a good fit to have a simple streamfield with only one block type: PageChooseBlock, which works fine, but I now have two questions regarding PageChooserBlocks:

1. How do I reverse lookup these blocks in the models being chosen? Author pages list all the books by that author. I have set a related name for the PageChooserBlock, but can't seem to access it in my lookups as it lives within the Streamfield, which I'm not sure .
2. Can I restrict PageChooserBlock to select only specific page types, as I can do with ForeignKey to restrict to a particular model?

I suppose I have a third question:

Is this a good idea? Should I be using an asymmetrical ManyToMany field instead? Is that a better/faster/cleaner implementation? I know I can certainly limit the page type selection that way.

Many thanks,
-Nick

Matthew Westcott

unread,
Jan 8, 2016, 9:28:22 AM1/8/16
to wag...@googlegroups.com
Hi Nick,
This is the downside of using StreamField I'm afraid - there's no way to do reverse lookups, as the data isn't being stored in a regular database relation.
Wagtail doesn't currently support ManyToMany fields either, but you can work around this by defining an intermediate model that links the two page types (which I'd call BookAuthor or BookAuthorship here), and making that an inline child model of Book <http://docs.wagtail.io/en/v1.3/topics/pages.html#inline-models>:

from modelcluster.fields import ParentalKey
from wagtail.wagtailcore.models import Orderable

class BookAuthorship(Orderable):
page = ParentalKey('myapp.BookPage', related_name='authors')
author = models.ForeignKey('myapp.AuthorPage', related_name='book_authorships')

panels = [
PageChooserPanel('author'),
]


class BookPage(Page):
...
content_panels = Page.content_panels + [
InlinePanel('authors'),
]


To answer your other question - it's not currently possible to restrict PageChooserBlock by page type. We have a pull request to implement that, but it's currently incomplete: https://github.com/torchbox/wagtail/pull/1531

Cheers,
- Matt

Nick Barreto

unread,
Jan 8, 2016, 9:42:27 AM1/8/16
to Wagtail support
Hi Matt,

Thanks a lot!

It does look like inline models will give me the functionality I'm after – a repeatable ForeignKey will do just the trick.

Between the docs and these examples you've posted, I think I've got it sussed out. If I have any issues with the implementation I'll let you know.

Also good to understand limitations of streamfields, etc. 

Cheers,
-Nick

Nick Barreto

unread,
Jan 8, 2016, 10:19:28 AM1/8/16
to Wagtail support
Hi Matt,

Having added the inline model to BookPage, and run migrations, etc, I'm now getting a TypeError when trying to load the admin page for a Bookpage:

childformset_factory() got an unexpected keyword argument 'validate_min'

(This is after also importing InlinePanel from wagtail.wagtailadmin.edit_handlers) 


This is the full traceback: http://pastebin.com/znnHsVqs

Am I missing something here? Did I forget to import another dependency?

Cheers,
-Nick

Matthew Westcott

unread,
Jan 8, 2016, 10:23:25 AM1/8/16
to wag...@googlegroups.com
Hi Nick,
It sounds like you're using an outdated version of the 'django-modelcluster' package - if you've got that listed in your requirements file, you should set it to: django-modelcluster>=1.1

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/38a38e28-80d0-4830-a3bc-61eabc3a37f8%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Nick Barreto

unread,
Jan 8, 2016, 10:39:45 AM1/8/16
to Wagtail support
Hey Matt,

Yep, that's sorted it. Thanks very much.

Cheers,
-Nick
Reply all
Reply to author
Forward
0 new messages