Getting Started with Wagtail and GraphQL
I was recently tasked with adding a CMS to an existing React application using GraphQL and Python+Django on the back end.
Wagtail was a perfect fit for this task because it is simple to drop in as a Django app, and was easy to expose to our GraphQL layer. The ability to integrate Wagtail with our existing domain models at the GraphQL layer meant that we could leverage our existing API calls inside an article with little more than a ForeignKey and a small resolver.
Assumptions
- Starting from a blank repository
- Python 3.6
- virtualenv
Installing Wagtail
- Follow Wagtail's Getting Started instructions.
- Stop the server
Add Blog App
Run python manage.py startapp blog
Update blog/models.py
with the following content:
# Taken From http://docs.wagtail.io/en/v1.9/getting_started/tutorial.html
from __future__ import unicode_literals
from django.db import models
# Create your models here.
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel
from wagtail.wagtailsearch import index
class BlogIndexPage(Page):
intro = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('intro', classname="full")
]
class BlogPage(Page):
date = models.DateField("Post date")
intro = models.CharField(max_length=250)
body = RichTextField(blank=True)
search_fields = Page.search_fields + [
index.SearchField('intro'),
index.SearchField('body'),
]
content_panels = Page.content_panels + [
FieldPanel('date'),
FieldPanel('intro'),
FieldPanel('body', classname="full"),
]
Install Graphene
Run pip install "graphene-django==1.2"
Configure Graphene
Add additional graphene settings to base.py
GRAPHENE = {
'SCHEMA': 'api.schema.schema',
}
Add an API app
Make a new folder at the root of mysite
, called api
Add apps.py
Make a new file inside the new api
folder called apps.py
, and paste in the following:
from django.apps import AppConfig
class ApiConfig(AppConfig):
name = 'api'
Add schema.py
Make another new file inside the api
folder named schema.py
with the following contents:
from __future__ import unicode_literals
import graphene
from graphene_django import DjangoObjectType
from blog.models import BlogPage
from django.db import models
class ArticleNode(DjangoObjectType):
class Meta:
model = BlogPage
only_fields = ['id', 'title', 'date', 'intro', 'body']
class Query(graphene.ObjectType):
articles = graphene.List(ArticleNode)
@graphene.resolve_only_args
def resolve_articles(self):
return BlogPage.objects.live()
schema = graphene.Schema(query=Query)
Configure URLs
Add two new imports to your urls.py
file.
from django.views.decorators.csrf import csrf_exempt
from graphene_django.views import GraphQLView
Add two new URLs to your urls.py
file, just above the Wagtail entry.
url(r'^api/graphql', csrf_exempt(GraphQLView.as_view())),
url(r'^api/graphiql', csrf_exempt(GraphQLView.as_view(graphiql=True, pretty=True))),
Add the new apps to settings
INSTALLED_APPS = (
# ... previously installed apps
'api',
'blog',
'graphene_django',
)
Commit new models
Run python manage.py makemigrations
Run python manage.py migrate
Start your local server
Run python manage.py runserver
Make a new blog entry
- Access the wagtail admin at http://localhost:8000/admin/.
- Using the menu, navigate to
Explorer
>Home Page
and clickAdd Child Page
- Add a new page of type
BlogPage
- Fill in all the fields
- Save & publish
Test GraphQL
Navigate to http://localhost:8000/api/graphiql and run the query below:
query articles {
articles {
id
title
date
intro
body
}
}
Editor's note: see Supporting StreamFields, Snippets and Images in a Wagtail GraphQL API for a continuation of this post.