WA

Wagtail

Developer-friendly Django CMS with a great editor experience

Content Management Systems ★ 20.5k stars Medium setup BSD-3-Clause

Wagtail is an open-source Django content management system focused on a refined editor experience and developer flexibility. It powers many large, content-rich websites with structured page models.

Key features

  • Refined editor interface
  • StreamField flexible content
  • Headless API option
  • Strong accessibility focus

Pros & cons

Strengths

  • Excellent editing experience
  • Great for Python developers

Trade-offs

  • Requires Django expertise
  • Heavier hosting needs

Wagtail replaces

Last reviewed Aug 26, 2026 · 786 words

Wagtail is the CMS to pick when a Python developer will own the site, and the wrong pick when nobody will. There is no installer: wagtail start mysite scaffolds a Django project, and from then on every content type is a Python model with a migration. In return you get the best editing interface in open-source CMS, StreamField for structured content that editors cannot break, an accessibility record that wins public-sector work, and pages that render in tens of milliseconds because there is no plugin soup. Those two facts decide it; the rest of this guide is the detail.

The first hour is a Django project, not an app install

python -m venv .venv && source .venv/bin/activate
pip install wagtail
wagtail start mysite && cd mysite
pip install -r requirements.txt
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver

The admin is at /admin/ and the scaffold includes a home app with a HomePage model. Adding a blog means writing a BlogPage(Page) class with fields, running makemigrations and migrate, and writing a template. If those commands are foreign, WordPress will make you happier this month; the CMS category sorts the options by who is doing the maintaining.

StreamField is the reason to bother

Most CMSs give editors one big rich-text box, and every long page becomes an HTML swamp. StreamField instead defines a page body as a sequence of typed blocks, each with its own form:

from wagtail.models import Page
from wagtail.fields import StreamField
from wagtail import blocks
from wagtail.images.blocks import ImageChooserBlock
from wagtail.admin.panels import FieldPanel

class ArticlePage(Page):
    body = StreamField([
        ("heading", blocks.CharBlock()),
        ("paragraph", blocks.RichTextBlock()),
        ("image", ImageChooserBlock()),
        ("quote", blocks.BlockQuoteBlock()),
    ])
    content_panels = Page.content_panels + [FieldPanel("body")]

Editors get a clean block-picker, you get JSON you can render into HTML, RSS, or a headless API without regret, and redesigns become template changes rather than content migrations. Combine it with the page tree (every page has a parent, permissions inherit down), scheduled publishing, workflows and per-page revisions, and the "refined editor interface" claim holds up in front of real editors.

Production is Postgres, gunicorn and something to serve files

The runserver above is for development. The stack that holds up: PostgreSQL (SQLite works but its full-text search is the weak spot), gunicorn with 2 to 3 workers at roughly 150 MB each, and either WhiteNoise for static files or Caddy serving static/ and media/ directly and proxying the rest. That lands on the 1 GB the catalogue lists for a small site. Wagtail's image handling is the resource surprise: every rendition (thumbnail, hero, card) is generated by Pillow on first request and cached, so the first crawl after a redesign is CPU-heavy and then quiet. Search uses the database backend by default, which is fine to around 10,000 pages; past that, or for relevance tuning, plug in Elasticsearch or OpenSearch.

Back up two things together: the database and media/. The database references uploads by path, and restoring one without the other yields a site full of broken images.

Headless works, but Wagtail is best when it renders itself

Wagtail exposes pages, images and documents through its built-in REST API (wagtail.api.v2), and GraphQL is available through the third-party wagtail-grapple package. Teams use it under Next.js or Astro front-ends and it works. Still, the page preview, the live-edit experience and the URL routing are all strongest when Django renders the templates. If headless is the whole point and Python is not, Directus or Strapi wrap a database with less ceremony.

Upgrades follow Django's cadence, and LTS makes it calm

Wagtail publishes an LTS release yearly with an extended support window, and each release names the Django versions it supports. Upgrade Wagtail and Django in step, read the release notes for deprecations, and run python manage.py makemigrations --check in CI so a schema drift never reaches production. A site on LTS releases needs attention twice a year; that is the honest maintenance number, and it is lower than a WordPress site with 20 plugins.

What I'd do

Only choose Wagtail if someone on the project writes Python without complaint. If they do: Postgres, gunicorn behind Caddy, media/ on a volume backed up alongside the database, StreamField for every long-form page from the start, LTS releases only. Skip headless until a second front-end genuinely exists. For a marketing site, a publication, or an organisation with actual editors, it is the most pleasant CMS I have handed to non-technical people, precisely because a developer laid the rails first.

Compare Wagtail

25 head-to-head comparisons.

Similar content management systems apps