Dustin Holden
Dustin Holden

Reputation: 180

Is there a way to use Wagtail Snippets to display existing Django Models?

With Wagtail CMS, what is the best way to mimic the "Plugin" functionality of Django CMS?

In Django CMS I am able to write a custom plugin that can display a template and any related information to that model. Content Managers can then add that plugin to a placeholder anywhere on the site.

With Wagtail, the closest thing I can find is the Snippet, but each time you use the Snippet you have to include it specifically in the Page model.

Take these two models for example:

class Pet(models.Model):
   species = models.CharField(max_length=10)
   name = models.CharField(max_length=100)

class Book(models.Model):
   title = models.CharField(max_length=100)
   author = models.CharField(max_length=100)

For the content manager to be able to access these I'd need to register them as snippets, and then list each model in that page's model like so:

class HomePage(Page):
    content_panels = Page.content_panels + [
        SnippetChooserPanel('pet'),
        SnippetChooserPanel('book'),
    ]

Is there a better way to do this with Wagtail?

Upvotes: 0

Views: 1536

Answers (2)

LB Ben Johnston
LB Ben Johnston

Reputation: 5176

To achieve this kind of solution with a generic defined template you could define a method on both the Book and Pets classes.

Something like:

from django.template.loader import render_to_string
from django.utils.safestring import mark_safe


class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    template = 'path/to/template.html'

    get_as_html(self):
        return mark_safe(render_to_string(self.template, {'self': self}))

You would need to create the template file that handles the Book instance. This means that you can easily call {{ Book.get_has_html }} within any templates that use the Book snippet.

Upvotes: 0

LB Ben Johnston
LB Ben Johnston

Reputation: 5176

To achieve this kind of solution without defining models you could look at the StreamField approach.

You could define a custom StreamField block type that models pets or books. Make this available on the pages that need this, you still have to be explicit about which pages can use this StreamField though.

You can then define a custom template that renders these items, available in the documentation:

http://docs.wagtail.io/en/v1.12.1/topics/streamfield.html#template-rendering

Upvotes: 2

Related Questions