Wagtail Tutorials #2: Create Page Model

Michael Yin

Full Stack Developer

Last updated on Jan 02 2021

Table of Contents


After you read this wagtail tutorial, you will learn

  1. How to create custom data models in Wagtail
  2. How Wagtail page tree works
  3. How to add page children and parent in Wagtail

Note: You can get the source code at the end of this tutorial so I ignored some import statements to help you focus on key point.

Step 1: Start to play with the page model

Let's get started! First, run python manage.py startapp blog to create new app in this Django project, then add blog to INSTALLED_APPS in wagtail_tuto/settings/base.py to enable it in this Django project.

In this blog app, now we need two types of model, one is BlogPage which is the root page of our blog site, it has some fields such as blog title, blog description. The other one is PostPage which has fields such as body to save the content of post page. All PostPage objects are chilredn of BlogPage.

Now edit blog/models.py

class BlogPage(Page):
    description = models.CharField(max_length=255, blank=True,)

    content_panels = Page.content_panels + [
        FieldPanel('description', classname="full")

class PostPage(Page):
    body = RichTextField(blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('body', classname="full"),

There are some points you should notice here, first, we create two models here, and they both inherit from the Page class from Wagtail.

Second, you can define custom fields as you wish, and you can use the fields from Django built-in fields or some fields from Wagtail. Here, the description is from Django and body is from Wagtail fields because we need more Wagtail support in Wagtail admin page. If the body is pure text object, then it would drive people crazy when editing it in admin page, but if we use RichTextField from wagtail, in edit page we will see a beautiful WYSIWYG rich text editor.

Third, we wrap the fields we created in the content_panels, which config how the fields are edited in wagtail admin. You should know that if you do not include your fields in content_panels, then you can not edit it in Wagtail admin page.

After we save the code, we need to migrate the DB.

python manage.py makemigrations
python manage.py migrate

Step 2: Hierarchical tree

I must say this part is the core part of Wagtail, however, many articles talking about Wagtail did not talk about this in detail. So you should read this part carefully and try to understand it well.

Now run the app using ./manage.py runserver and login into the admin page of Wagtail and take a look at it. Click Explorer/Home to enter the home page. Now this home page is the root page of the site, we create a single blog page as child of it. Click Add child page button in the top panel, choose Blog page and insert some text in title and description.

What you should be careful is the slug value in promote tab, because the url of this blog page will be generated as[slug]. Here to make it easy to understand, I set the value blog, so the url of this blog page become At last, we click publish button at the bottom to submit the values to database.

After we create a blog page, we can add some post pages as its children, we click Explorer/Home to go back to home page, and then click add child page in the blog page we just created, then choose Post page. What you should notice here is the button add child page in top panel is to add child to home page, and the add child page in the blog panel is to add child page to blog page, which has different effect. You can also see the difference from the title of link

We use this method to create multiple post pages as the children of blog page. If you want to see the list of children of blog, click the button in the next image.

Now the pages we just created will have tree structure like this.

    home/   ------> This one is the root page of our site

As you know, home is create by migration file and it has been set as root page of localhost, so now if we visit url, then content of blog page will display, and if we visit url then the content of post page 1 will display. Can you figure out something here?

Starting from the root page of that site, Wagtail traverses the page tree, calling the route() method and letting each page model decide whether it will handle the request itself or pass it on to a child page.

In this case, blog page pass the request to child page, that is why we can use to visit the blog post page.

Step 3: Create templates to show the content

Create blog/templates/blog/blog_page.html

{% load wagtailcore_tags %}

{% block content %}
    <h1>{{ page.title }}</h1>

    <div class="intro">{{ page.description }}</div>

    {% for post in page.get_children %}
        <h2><a href="{% pageurl post %}">{{ post.title }}</a></h2>
    {% endfor %}

{% endblock %}

Create blog/templates/blog/post_page.html

{% load wagtailcore_tags %}

{% block content %}
    <h1>{{ page.title }}</h1>

    {{ page.body|richtext }}

    <p><a href="{{ page.get_parent.url }}">Return to blog</a></p>

{% endblock %}

As you can see, in the template, we use get_children and get_parent to get the children and parent of the page, and we use page object to access the value of our page model because the two models create above are both sub class of Wagtail Page, and richtext filter to render richtext data. We will talk about custom Django filter in later chapter.

Now we can check the blog in browser.

We can click the post title to check post content.


In this chapter, we create a simple blog which has two basic models, and I hope you have a basic understanding of the hierarchical “tree”. You can keep learning Wagtail and the full list is here Wagtail tutorial series

The source code of this Wagtail tutorial is available on Github, you can get it here wagtail-bootstrap-blog, and I would appreciate that if you could star my repo.

Michael Yin

Michael is a Full Stack Developer from China who loves writing code, tutorials about Django, Wagtail CMS and React.

He has published some ebooks on leanpub and tech course on testdriven.io.

He is also the founder of the AccordBox which provides the web development services.

Table of Contents

This book will teach you how to build a modern blog with Wagtail CMS

Read More


Get notified about new great Web Development Tutorial