docs/reference/signals.md
Wagtail implements Signals from django.dispatch when managing models such as Revision, Page, and snippets.
Signals are useful for creating side-effects from Wagtail events such as publishing, unpublishing, and workflow progress.
For example, you could use signals to send publish notifications to a messaging service, or POST messages to another app that's consuming the API, such as a static site generator.
To listen to a signal, register a signal receiver using the Signal.connect() method. Here's an
example showing how you might use the page_published signal to notify your team when a page is published:
from wagtail.signals import page_published
import requests
# Let everyone know when a new page is published
def send_to_slack(sender, **kwargs):
instance = kwargs['instance']
url = 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX'
values = {
"text" : "%s was published by %s " % (instance.title, instance.owner.username),
"channel": "#publish-notifications",
"username": "the squid of content",
"icon_emoji": ":octopus:"
}
response = requests.post(url, values)
# Register a receiver
page_published.connect(send_to_slack)
Sometimes you're not interested in receiving signals for every model, or you want
to handle signals for specific models in different ways. You can specify the
sender argument when connecting to a signal to only receive signals from a
specific model. For instance, you may wish to do something when a new blog post
is published:
from wagtail.signals import page_published
from mysite.models import BlogPostPage
# Do something clever for each model type
def receiver(sender, **kwargs):
# Do something with blog posts
pass
# Register listeners for each page model class
page_published.connect(receiver, sender=BlogPostPage)
Wagtail provides access to a list of registered page types through the get_page_models() function in wagtail.models.
Read the Django documentation for more information about specifying senders.
(signal_published)=
publishedThis signal is emitted from a Revision when a revision of any model (including pages) is published.
sender - The model class of the published object.instance - The specific model instance that was published.revision - The Revision that was published.kwargs - Any other arguments passed to published.send().(signal_page_published)=
page_publishedThis signal is emitted from a Revision when a page revision is published, similar to published.
It is useful if you want to receive signals only for page publishing events, without having to specify the sender for each page model class.
sender - The page class.instance - The specific Page instance.revision - The Revision that was published.kwargs - Any other arguments passed to page_published.send().(signal_unpublished)=
unpublishedThis signal is emitted when any model instance (including pages) is unpublished.
sender - The model class of the unpublished object.instance - The specific model instance that was unpublished.kwargs - Any other arguments passed to unpublished.send().(signal_page_unpublished)=
page_unpublishedThis signal is emitted from a Page when the page is unpublished, similar to unpublished.
It is useful if you want to receive signals only for page unpublishing events, without having to specify the sender for each page model class.
sender - The page class.instance - The specific Page instance.kwargs - Any other arguments passed to page_unpublished.send()pre_page_move and post_page_moveThese signals are emitted from a Page immediately before and after it is moved.
Subscribe to pre_page_move if you need to know values BEFORE any database changes are applied. For example: Getting the page's previous URL, or that of its descendants.
Subscribe to post_page_move if you need to know values AFTER database changes have been applied. For example: Getting the page's new URL, or that of its descendants.
The following arguments are emitted for both signals:
sender - The page class.instance - The specific Page instance.parent_page_before - The parent page of instance before moving.parent_page_after - The parent page of instance after moving.url_path_before - The value of instance.url_path before moving.url_path_after - The value of instance.url_path after moving.kwargs - Any other arguments passed to pre_page_move.send() or post_page_move.send().The signal can be emitted as a result of a page being moved to a different section (a 'move'), or as a result of a page being moved to a different position within the same section (a 'reorder'). Knowing the difference between the two can be particularly useful, because only a 'move' affects a page's URL (and that of its descendants), whereas a 'reorder' only affects the natural page order; which is probably less impactful.
The best way to distinguish between a 'move' and 'reorder' is to compare the url_path_before and url_path_after values. For example:
from wagtail.signals import pre_page_move
from wagtail.contrib.frontend_cache.utils import purge_page_from_cache
# Clear a page's old URLs from the cache when it moves to a different section
def clear_page_url_from_cache_on_move(sender, **kwargs):
if kwargs['url_path_before'] == kwargs['url_path_after']:
# No URLs are changing :) nothing to do here!
return
# The page is moving to a new section (possibly even a new site)
# so clear old URL(s) from the cache
purge_page_from_cache(kwargs['instance'])
# Register a receiver
pre_page_move.connect(clear_old_page_urls_from_cache)
(page_slug_changed)=
page_slug_changedThis signal is emitted from a Page when a change to its slug is published.
The following arguments are emitted by this signal:
sender - The page class.instance - The updated (and saved), specific Page instance.instance_before - A copy of the specific Page instance from before the changes were saved.(init_new_page_signal)=
init_new_pageThis signal is emitted from a CreateView when a new page is initialized in the admin interface. In other words, it's emitted when a user navigates to a form to create a new page.
It's useful for pre-populating the page form programmatically when default values are not sufficient.
sender - CreateViewpage - The new page instanceparent_page - The parent page of the new pageHere's an example of how to use this signal to pre-populate a new page's title using the page's parent's title as a prefix:
from wagtail.signals import init_new_page
def prepopulate_page(sender, page, parent, **kwargs):
if parent:
page.title = f"{parent.title}: New Page Title"
init_new_page.connect(prepopulate_page)
For more complex customizations of the page creation and editing forms, see .
The following signals apply to pages and snippets with workflows enabled.
workflow_submittedThis signal is emitted from a WorkflowState when a model is submitted to a workflow.
sender - WorkflowStateinstance - The specific WorkflowState instance.user - The user who submitted the workflowkwargs - Any other arguments passed to workflow_submitted.send()workflow_rejectedThis signal is emitted from a WorkflowState when a model is rejected from a workflow.
sender - WorkflowStateinstance - The specific WorkflowState instance.user - The user who rejected the workflowkwargs - Any other arguments passed to workflow_rejected.send()workflow_approvedThis signal is emitted from a WorkflowState when a model's workflow completes successfully.
sender - WorkflowStateinstance - The specific WorkflowState instance.user - The user who last approved the workflowkwargs - Any other arguments passed to workflow_approved.send()workflow_cancelledThis signal is emitted from a WorkflowState when a model's workflow is cancelled.
sender - WorkflowStateinstance - The specific WorkflowState instance.user - The user who cancelled the workflowkwargs - Any other arguments passed to workflow_cancelled.send()task_submittedThis signal is emitted from a TaskState when a model is submitted to a task.
sender - TaskStateinstance - The specific TaskState instance.user - The user who submitted the page to the taskkwargs - Any other arguments passed to task_submitted.send()task_rejectedThis signal is emitted from a TaskState when a model is rejected from a task.
sender - TaskStateinstance - The specific TaskState instance.user - The user who rejected the taskkwargs - Any other arguments passed to task_rejected.send()task_approvedThis signal is emitted from a TaskState when a model's task is approved
sender - TaskStateinstance - The specific TaskState instance.user - The user who approved the taskkwargs - Any other arguments passed to task_approved.send()task_cancelledThis signal is emitted from a TaskState when a model's task is cancelled.
sender - TaskStateinstance - The specific TaskState instance.user - The user who cancelled the taskkwargs - Any other arguments passed to task_cancelled.send()copy_for_translation_doneThis signal is emitted from CopyForTranslationAction or CopyPageForTranslationAction when a translatable model or page is copied to a new locale (translated).
A translatable model is a model that implements the TranslatableMixin.
sender - CopyForTranslationAction or CopyPageForTranslationActionsource_obj - The source objecttarget_obj - The copy of the source object in the new locale