Unreleased
---
local:
depth: 1
---
django-tasks
Wagtail now integrates with the django-tasks library to allow moving computationally-intensive tasks out of the request-response cycle, and improving the performance of the Wagtail admin interface. These tasks include:
In the default configuration, these tasks are executed immediately within the request-response cycle, as they were in previous versions of Wagtail. However, by configuring the TASKS
setting with an appropriate backend as per the django-tasks documentation, these tasks can be deferred to a background worker process.
This feature was developed by Jake Howard.
You can now set up previews for StreamField blocks. The preview will be shown in the block chooser, along with a description for the block. This feature can help users choose the right block when writing content inside a StreamField. To enable this feature, see [](configuring_block_previews).
This feature was developed by Sage Abdullah and Thibaud Colas.
The new [](headless) documentation page curates important information about Wagtail’s headless capabilities, directly within the developer documentation. This is the foundation for a headless improvements roadmap for Wagtail.
Thank you to Sævar Öfjörð Magnússon and Alex Fulcher for creating this new page at the Wagtail Space NL 2024 sprint.
Building upon improvements in past versions, this releases comes with further enhancements to alt text management:
alt-text-quality
content check.Thank you to Matt Westcott, Thibaud Colas, and Cynthia Kiser for their work on these improvements.
FieldPanel
and InlinePanel
Plain strings can now be used in panel definitions as a substitute for FieldPanel
and InlinePanel
, avoiding the need to import these classes from wagtail.admin.panels
:
class MyPage(Page):
body = RichTextField()
content_panels = [
'body',
]
This feature was developed by Matt Westcott.
The StreamField and InlinePanel interfaces now support drag-and-drop reordering of items within a field. This makes it faster to rearrange content within these fields, particularly when there is a lot of content.
This feature was developed by Thibaud Colas and Sage Abdullah, thanks to a sponsorship by Lyst.
specific()
sub-queries using select_related
& prefetch_related
, see [](../reference/pages/queryset_reference.md) (Andy Babic)DATA_UPLOAD_MAX_NUMBER_FIELDS
in project template (Matt Westcott)allowed_http_methods
(Andy Babic)on_serve_page
hook to modify the serving chain of pages (Krystian Magdziarz, Dawid Bugajewski)WAGTAIL_GRAVATAR_PROVIDER_URL
URLs with query string parameters (Ayaan Qadri, Guilhem Saurel)get_avatar_url
hook to customise user avatars (James Harrington)page
as a third parameter to the construct_wagtail_userbar
hook (claudobahn)Fuzzy
queries (Tom Usher)StreamField
values do not throw an error (Stefan Hammer)StreamField.get_default()
to prevent creation forms from breaking (Matt Westcott)read_only
FieldPanel
s in use (Strapchay)th
(table heading) elements that are not compliant with accessibility standards (Jai Vignesh J)MultipleChooserPanel
using images or documents work when nested within an InlinePanel
when no other choosers are in use within the model (Elhussein Almasri)MultipleChooserPanel
works after doing a search in the page chooser modal (Matt Westcott)ListBlock
instances get created with unique IDs in the admin client for accessibility and mini-map element references (Srishti Jaiswal)get_block_by_content_path
on ImageBlock
to prevent errors on commenting (Matt Westcott)aria-expanded
attribute to new column button on TypedTableBlock
to reflect menu state (Ayaan Qadri, Scott Cranfill)Page
panel definitions without importing wagtail.admin
(Matt Westcott)WidgetWithScript
by raising it with stacklevel=3
(Joren Hammudoglu)FilterField("created_at")
to AbstractDocument
to fix ordering by created_at
after searching in the documents index view (Srishti Jaiswal)Site.find_for_request()
from Page.get_url_parts()
(Andy Babic)StreamChildrenToListBlockOperation
from duplicating data across multiple StreamField instances (Joshua Munn)wagtail start
command to the management commands reference page (Damilola Oladele)DATA_UPLOAD_MAX_NUMBER_FIELDS
when integrating Wagtail into Django (Matt Westcott)mark_safe
to format_html
for any script inclusions, to better avoid XSS issues from example code (Aayushman Singh)AbstractEmailForm
or AbstractForm
pages (John-Scott Atlakson, LB (Ben) Johnston)BlogTagIndexPage
example for clarity (Clifford Gama)wagtailcache
and wagtailpagecache
examples to not use quotes for the fragment_name
(Shiv)HTTPMethod
in Page.handle_options_request()
docs (Sage Abdullah)FieldPanel
/ InlinePanel
where appropriate (Unyime Emmanuel Udoh)get_template
method on StreamField blocks (Matt Westcott)ALLOWED_HOSTS
check in Site.find_for_request
(Jake Howard)CloneController
to ensure that added
/cleared
events are not dispatched as cancelable (LB (Ben) Johnston)uuid
UMD module as all code is now using the NPM module (LB (Ben) Johnston)eslint-disable no-undef
linter directives with global
comments (LB (Ben) Johnston)PreviewController
usage to leverage Stimulus actions instead of calling preventDefault
manually (Ayaan Qadri)ZoneController
(w-zone
) to support dynamic class name changes & event handling on container elements (Ayaan Qadri)ModalWorkflow
(LB (Ben) Johnston)delay
value in TagController
to debounce async autocomplete tag fetch requests (Aayushman Singh)DrilldownController
(Srishti Jaiswal)LinkController
(w-link
) (Sage Abdullah)EditView
to make better use of generic EditView
(Sage Abdullah)RulesController
(w-rules
) to support declarative conditional field enabling from other field values in a form (LB (Ben) Johnston)RulesController
(w-rules
) approach (LB (Ben) Johnston)ZoneController
(w-zone
) to support inactive class and a mechanism to switch the mode based on data within events (Ayaan Qadri)ZoneController
(w-zone
) to remove ad-hoc jQuery for the privacy switch when toggling visibility of private/public elements (Ayaan Qadri)is_active
& active_menu_items
from wagtail.admin.menu.MenuItem
(Srishti Jaiswal)openpyxl
at runtime to improve performance for projects that do not use ReportView
, SpreadsheetExportMixin
and wagtail.contrib.redirects
(Sébastien Corbin)mp
instead of mm
for 'mystery person' as the default Gravatar if no avatar found (Harsh Dange)venv
instead of pipenv
in CircleCI (Sage Abdullah)FormsetController
(w-formset
) to support dynamic formset insertion/deletion behavior (LB (Ben) Johnston)revisions_revert
view to be a subclass of EditView
(Sage Abdullah)get_usage().count()
call to view code (Sage Abdullah)DATA_UPLOAD_MAX_NUMBER_FIELDS
updateIt's recommended that all projects set the DATA_UPLOAD_MAX_NUMBER_FIELDS
setting to 10000 or higher.
This specifies the maximum number of fields allowed in a form submission, and it is recommended to increase this from Django's default of 1000, as particularly complex page models can exceed this limit within Wagtail's page editor:
# settings.py
DATA_UPLOAD_MAX_NUMBER_FIELDS = 10_000
related_name
On previous releases, form page models (defined through AbstractEmailForm
, AbstractForm
, FormMixin
or EmailFormMixin
) did not validate form fields where the related_name
was different to the default value of form_fields
. As a result, it was possible to create forms with duplicate field names - in this case, only a single field is displayed and captured in the resulting form. As of Wagtail 6.4, validation is now applied on these fields. Existing forms will continue to behave as before and no data will be lost, but editing them will now raise a validation error.
In the default configuration, tasks managed by django-tasks
(see above) run during the request-response cycle, as before. However, they are now deferred until the current transaction (if any) is committed. If ATOMIC_REQUESTS
is set to True
, this will be at the end of the request. This may lead to a change of behaviour on views that expect to see the results of these tasks immediately, such as a view that creates a page and then performs a search query to retrieve it. To restore the previous behaviour, set "ENQUEUE_ON_COMMIT": False
in the TASKS
setting:
# settings.py
TASKS = {
"default": {
"BACKEND": "django_tasks.backends.immediate.ImmediateBackend",
"ENQUEUE_ON_COMMIT": False,
}
}
Django's test framework typically runs tests inside transactions, and so this situation is also likely to arise in tests that perform database updates and then - within the same test - expect these changes to be immediately reflected in search queries, object usage counts, and other processes that are now handled with background tasks. This can be addressed by setting ENQUEUE_ON_COMMIT
to False
as above in the test settings, or by wrapping the database updates in with self.captureOnCommitCallbacks(execute=True)
to ensure that these tasks are completed before the test continues:
def test_search(self):
home_page = Page.objects.get(slug="home")
with self.captureOnCommitCallbacks(execute=True): # Added
home_page.add_child(instance=EventPage(title="Christmas party"))
response = self.client.get("/search/?q=Christmas")
self.assertContains(response, "Christmas party")
page
as a third parameter to the construct_wagtail_userbar
hookIn previous releases, implementations of the construct_wagtail_userbar
hook were expected to accept two arguments, whereas now page
is passed in as a third argument.
Old
@hooks.register('construct_wagtail_userbar')
def construct_wagtail_userbar(request, items):
pass
New
@hooks.register('construct_wagtail_userbar')
def construct_wagtail_userbar(request, items, page):
pass
The old style will now produce a deprecation warning.
content_panels
, promote_panels
and settings_panels
values on base Page
modelPreviously, the content_panels
, promote_panels
and settings_panels
attributes on the base Page
model were defined as lists of Panel
instances. These lists now contain instances of wagtail.models.PanelPlaceholder
instead, which are resolved to Panel
instances at runtime. Panel definitions that simply extend these lists (such as content_panels = Page.content_panels + [...]
) are unaffected; however, any logic that inspects these lists (for example, finding a panel in the list to insert a new one immediately after it) will need to be updated to handle the new object types.
The unused JavaScript include wagtailadmin/js/vendor/rangy-core.js
has been removed from the editor interface, and functions such as window.rangy.getSelection()
are no longer available. Any code relying on this should now either supply its own copy of the Rangy library, or be migrated to the official Document.createRange()
browser API.
window.buildExpandingFormset
global functionThe undocumented global function window.buildExpandingFormset
to attach JavaScript insertion / deletion behavior for Django formsets has been deprecated and will be removed in a future release.
Within the Wagtail admin this only impacts a small set of basic expanding formsets in use across Workflow and Group view editing. InlinePanel
is not affected.
Previously these expanding formsets required a mix of specific id attribute structures and inline scripts to instantiate with callbacks for handling deletion. User code implementing this functionality through buildExpandingFormset
should be updated - the following data attributes can be used to emulate the same behavior. These are likely to change and should not be considered official documentation.
Element | Attribute(s) |
---|---|
Containing element | data-controller="w-formset" |
Element to append new child forms | data-w-formset-target="forms" |
Child form element | data-w-formset-target="child" |
Deleted form element | data-w-formset-target="deleted" hidden |
template element for blank form |
data-w-formset-target="template" |
Management field (total forms) | data-w-formset-target="totalFormsInput" |
Management field (min forms) | data-w-formset-target="minFormsInput" |
Management field (max forms) | data-w-formset-target="maxFormsInput" |
Management field (Delete, within child form) | data-w-formset-target="deleteInput" |
Add child button |
data-action="w-formset#add" |
Delete child button (within child form) |
data-action="w-formset#delete" |
Usage of nested id structures are no longer required but can be left in place for easier debugging.