Get started


6 May 2020

Wagtail 2.9

A new month is upon us, and with it comes a new release of Wagtail. 2.9 may not be the most dramatic update in terms of user-facing features, but it brings some key improvements to the developer experience, fixing some long-standing bugbears.

Matt Westcott

Matt Westcott

Wagtail core team

Before we dive in to the new features, an important announcement: this release includes a security fix for a potential vulnerability in password-protected private pages. While this is on the theoretical end of the scale, rather than something likely to be exploited on real-world world websites, it's always best to err on the side of caution, and so we'd recommend upgrading as soon as possible. For sites that can't be upgraded right away, or are running the 2.7 Long-Term Support branch, this fix has been released separately as Wagtail 2.7.3 and 2.8.2.

Wagtail 2.8 introduced a new Reports area as part of the improved page locking feature, and this has been extended in 2.9 with the ability to build your own reports. Report data can be exported in XLSX or CSV format - an option that's now also available on ModelAdmin listings (with some simple additional configuration) and form builder submissions.

One change in particular may take some getting used to for long-time Wagtail developers - we've started to phase out SiteMiddleware and the variable. This has been around since the start of Wagtail as a convenient way to access the site record for the current request, but it has its drawbacks: it clashes with CurrentSiteMiddleware from Django's own sites framework, and adds an up-front database query to every request, even on pure Django views that have no connection to Wagtail. Efficient alternatives to are available in the form of Site.find_for_request and the {% wagtail_site %} template tag, so developers who are keen to see the back of SiteMiddleware can now drop it from their MIDDLEWARE lists. If eliminating from your codebase is going to be a marathon task, don't worry – it will still be supported until Wagtail 2.11.

Headless deployments continue to be a popular approach for keeping front-end and back-end concerns separated, but up to now the Wagtail admin has never fully embraced the possibility that the Django-side page templates might not match what the end user sees (if indeed they're defined at all). Wagtail 2.9 fixes that – previews and 'view draft' links can be disabled by setting an empty preview_modes attribute on a page model, and the admin backend can now run happily without the front-end 'serve' view being defined in the project's URL config.

Wagtail 2.9 also brings new possibilities for tagging. The underlying django-taggit library has long supported custom tag models – so that your special-purpose page models don't have to share the same pool of tags as images and documents – but previously the Wagtail admin would fail to pick up on this, and offer autocompletion suggestions based on the default tag model instead. This has now been rectified – Wagtail will now recognise the tag model in use and adapt its suggestions accordingly. In addition, free tagging can be disabled for a custom tag model, meaning that tags can no longer be brought into existence simply by using them - instead, they're taken from a pre-determined list set up through snippets or ModelAdmin.

There are some updates to StreamField, too - ChoiceBlock now has a multiple-select counterpart, MultipleChoiceBlock, and performance improvements have been made to CSS / JavaScript handling on complex nested blocks, as well as bulk fetching of database objects inside ListBlocks. Further performance improvements are made possible with the new support for cached image renditions.

There's much more that we haven't mentioned, including many of the accessibility fixes completed at the Bristol Wagtail sprint in January - as always, the release notes have the full lowdown.