-
-
Save mx-moth/3194d77af88f26217a7e to your computer and use it in GitHub Desktop.
Many to many relationships in Wagtail
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import models | |
from wagtail.wagtailsnippets.models import register_snippet | |
from wagtail.wagtailcore.models import Page | |
from wagtail.wagtailadmin.edit_handlers import InlinePanel | |
@register_snippet | |
class Category(models.Model): | |
""" | |
There can be many categories related to many posts. | |
""" | |
title = models.CharField(max_length=255) | |
class Post(Page): | |
""" | |
There can be many posts related to many categories. | |
""" | |
# A standard ManyToMany field can be added, even if it is used by | |
# the edit handlers. | |
categories = models.ManyToManyField( | |
Category, through='PostCategory', related_name='+') | |
# Only inline panels work here. | |
content_panels = Page.content_panels + [ | |
# This name comes from the "related_name" field explained below. | |
InlinePanel('post_category_relationship') | |
] | |
class PostCategoryRelationship(models.Model): | |
""" | |
An index of references between posts and categories. | |
This is where the relationship is defined. | |
Ex. a post with three categories will create three rows in this table. | |
For instance, a post titled "Bitcoin is dead" in the categories | |
"tech", "finance", and "life" will create the following rows: | |
row = 1 | |
post = "Bitcoin is dead" | |
category = "tech" | |
row = 2 | |
post = "Bitcoin is dead" | |
category = "finance" | |
row = 3 | |
post = "Bitcoin is dead" | |
category = "life" | |
""" | |
# The post this relationship is for. | |
# ParentalKey is just like ForeignKey, but needed for Wagtail's "preview" | |
# function to work. More: https://github.com/torchbox/django-modelcluster | |
post = ParentalKey( | |
'Post', | |
related_name='post_category_relationship' | |
) | |
# The "related name" allows us to grab rows from this table with a post. | |
# It creates a new property on all posts that you can access like so: | |
# | |
# my_post.post_category_relationship | |
# The category related to this post | |
category = models.ForeignKey( | |
'Category', | |
related_name="+" | |
) | |
panels = [ | |
FieldPanel('category') | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import models | |
from wagtail.wagtailsnippets.models import register_snippet | |
from wagtail.wagtailcore.models import Page | |
from wagtail.wagtailadmin.edit_handlers import InlinePanel | |
@register_snippet | |
class Category(models.Model): | |
title = models.CharField(max_length=255) | |
class Post(Page): | |
categories = models.ManyToManyField( | |
Category, through='PostCategory', related_name='+') | |
content_panels = Page.content_panels + [ | |
InlinePanel('post_category_relationship') | |
] | |
class PostCategoryRelationship(models.Model): | |
post = ParentalKey( | |
'Post', | |
related_name='post_category_relationship' | |
) | |
category = models.ForeignKey( | |
'Category', | |
related_name="+" | |
) | |
panels = [ | |
FieldPanel('category') | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% if page.categories %} | |
<ul class="categories"> | |
{% for category in page.categories.all %} | |
<li>{{ category.title }}</li> | |
{% endfor %} | |
</ul> | |
{% endif %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment