Skip to content

Instantly share code, notes, and snippets.

@mx-moth
Forked from alexgleason/m2m.py
Last active August 3, 2016 00:22
Show Gist options
  • Save mx-moth/3194d77af88f26217a7e to your computer and use it in GitHub Desktop.
Save mx-moth/3194d77af88f26217a7e to your computer and use it in GitHub Desktop.
Many to many relationships in Wagtail
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')
]
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')
]
{% 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