After reading this Wagtail tip article, you will get:
ParentalManyToManyFieldmight bring to your project.
How to replace
ParentalManyToManyFieldusing Wagtail InlinePanel
Step 1 - Add ParentalManyToManyField to your project
In Wagtail doc,
ParentalManyToManyField is imported to help user build relationship between category and page. Below is the code snippet
class PostPage(Page): categories = ParentalManyToManyField('blog.BlogCategory', blank=True) content_panels = Page.content_panels + [ FieldPanel('categories', widget=forms.CheckboxSelectMultiple), ] @register_snippet class BlogCategory(models.Model): name = models.CharField(max_length=255) slug = models.SlugField(unique=True, max_length=80) panels = [ FieldPanel('name'), FieldPanel('slug'), ] def __str__(self): return self.name class Meta: verbose_name = "Category" verbose_name_plural = "Categories"
As you can see, we register
BlogCategory as Wagtail snippet so we can add, edit in Wagtail snippet admin.
The magic here is the
categories = ParentalManyToManyField('blog.BlogCategory', blank=True) and code in
content_panels, now we can manage category of the post page using checkbox list.
Step 2 - Find out the problem
Cheers, now you have made Category work in your Wagtail project. but there are two problems with this solution.
If the category list is very long, is there a way to solve this problem? Can we just add category that we want to choose? What if you want to do nested Category?
If you want to migrate the data of your Wagtail project to another place using
Django dumpdata&loaddata, you will find out the category are gone even there is no error during the process.
To clarify the second point, you can do this
./manage.py dumpdata --natural-foreign --indent 2 -e auth.permission -e contenttypes -e wagtailcore.groupcollectionpermission -e wagtailimages.rendition -e sessions > data.json # config to use new db ./manage.py migrate ./manage.py loaddata data.json ./manage.py runserver
Then you can check in Wagtail admin, you will see the category of the post is gone.
Note: You can get a Github project at the bottom of this article to test on your own.
If you check the data.json by yourself, you will see even we use
natual-foreign to dump the data, the category info of page is still pk. I think that is why the loaddata fail here.
The only way to solve this problem is to write code to migrate data.
Step 3 - How to replace ParentalManyToManyField
What if you want to replace ParentalManyToManyField? Here I will show you how:
class PostPage(Page): content_panels = Page.content_panels + [ InlinePanel('categories2', label='category'), ] class BlogPageBlogCategory(models.Model): page = ParentalKey('blog.PostPage', on_delete=models.CASCADE, related_name='categories2') blog_category = models.ForeignKey( 'blog.BlogCategory', on_delete=models.CASCADE, related_name='blog_pages') panels = [ SnippetChooserPanel('blog_category'), ] class Meta: unique_together = ('page', 'blog_category')
Here we create
BlogPageBlogCategory as intermediate model, we can also add other fields as we like in the future.
page is ForeignKey to our PostPage and
blog_category is ForeignKey to BlogCategory.
unique_together here make sure no duplicate category are saved for one post.
Note: I use field name
categories2 to distinguish with previous
categoryies, but you should replace when copy&paste.
After you are done, please migrate your database and modify your template file to make that work.
If you have problem in this part, just feel free to contact me and I'd like to help if I have time.
Step 4 - Check again in Wagtail admin
InlinePanel, now category is more flexible, and we can add more settings to let us search, add category , or reorder category.
What is more, if you want to build nested Category in your Wagtail project, you can also use this way (I will talk about it in another blog).
You can get all source code of this article here Wagtail ParentalManyToManyField Example
In this Wagtail tip, we learned why we need to avoid using
ParentalManyToManyField and how to replace by creating intermediate model and
You can also check the full list of my wagtail tutorial here wagtail tutorial series