From 6cb463dd41b118af59fa70b144c5f4d23fcb40f6 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Tue, 28 Sep 2021 20:09:10 +0100 Subject: [PATCH] Document the new 'log' method --- docs/extending/audit_log.rst | 81 +++++++++++++++++++++++++++++------- docs/releases/2.15.rst | 11 +++++ 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/docs/extending/audit_log.rst b/docs/extending/audit_log.rst index 358f3e301a..ae1ec5d60d 100644 --- a/docs/extending/audit_log.rst +++ b/docs/extending/audit_log.rst @@ -11,26 +11,29 @@ registry of 'actions' that provide additional context for the logged action. The audit log-driven Page history replaces the revisions list page, but provide a filter for revision-specific entries. -.. note:: The audit log does not replace revisions +.. note:: The audit log does not replace revisions. -To provide additional ``Page`` logging for your site or package, invoke the :meth:`~PageLogEntryManger.log_action` manager method -via ``PageLogEntry.objects.log_action(object_instance, action)`` and register a ``register_log_actions`` hook to -describe your action (see :ref:`register_log_actions`). +The ``wagtail.core.log_actions.log`` function can be used to add logging to your own code. -.. note:: When adding logging, you need to log the action or actions that happen to the ``Page``. For example, if the - user creates and publishes, there should be a "create" entry and a "publish" entry. Or, if the user copies a - published page and chooses to keep it published, there should be a "copy" and a "publish" entry for new page. +.. function:: log(instance, action, user=None, uuid=None, title=None, data=None) -You can provide additional metadata by passing additional parameters: + Adds an entry to the audit log. -- ``user`` - a user object. -- ``data`` - a data dictionary, stored as JSON -- ``title`` - by default, Wagtail will attempt to use ``get_admin_display_title`` or the string representation of the passed object. + :param instance: The model instance that the action is performed on + :param action: The code name for the action being performed. This can be one of the names listed below, or a custom action defined through the :ref:`register_log_actions` hook. + :param user: Optional - the user initiating the action. For actions logged within an admin view, this defaults to the logged-in user. + :param uuid: Optional - log entries given the same UUID indicates that they occurred as part of the same user action (e.g. a page being immediately published on creation). + :param title: The string representation of the instance being logged. By default, Wagtail will attempt to use the instance's ``str`` representation, or ``get_admin_display_title`` for page objects. + :param data: Optional - a dictionary of additional JSON-serialisable data to store against the log entry + +.. note:: When adding logging, you need to log the action or actions that happen to the object. For example, if the + user creates and publishes a page, there should be a "create" entry and a "publish" entry. Or, if the user copies + a published page and chooses to keep it published, there should be a "copy" and a "publish" entry for new page. .. code-block:: python # mypackage/views.py - from wagtail.core.models import PageLogEntry + from wagtail.core.log_actions import log def copy_for_translation(page): # ... @@ -42,12 +45,15 @@ You can provide additional metadata by passing additional parameters: data = { 'make': {'it': 'so'} } - PageLogEntry.objects.log_action( - instance=page, action='mypackage.custom_action', user=request.user, data=data + log( + instance=page, action='mypackage.custom_action', data=data ) -To log actions for your non-page model, you can create a class that inherits from ``BaseLogEntry`` with the appropriate -linking. + +.. versionchanged:: 2.15 + + The ``log`` function was added. Previously, logging was only implemented for pages, and invoked through the ``PageLogEntry.objects.log_action`` method. + Log actions provided by Wagtail ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -84,3 +90,46 @@ Action Notes ``wagtail.workflow.resume`` The draft was resubmitted to the workflow ``wagtail.workflow.cancel`` The workflow was cancelled =================================== ===== + + +Log context +~~~~~~~~~~~ + +The ``wagtail.core.log_actions`` module provides a context manager to simplify code that logs a large number of actions, +such as import scripts: + +.. code-block:: python + + from wagtail.core.log_actions import LogContext + + with LogContext(user=User.objects.get(username='admin')): + # ... + log(page, 'wagtail.edit') + # ... + log(page, 'wagtail.publish') + + +All ``log`` calls within the block will then be attributed to the specified user, and assigned a common UUID. A log context +is created automatically for views within the Wagtail admin. + + +Log models +~~~~~~~~~~ + +Logs are stored in the database via the models ``wagtail.core.models.PageLogEntry`` (for actions on Page instances) and +``wagtail.core.models.ModelLogEntry`` (for actions on all other models). Page logs are stored in their own model to +ensure that reports can be filtered according to the current user's permissions, which could not be done efficiently +with a generic foreign key. + +If your own models have complex reporting requirements that would make ``ModelLogEntry`` unsuitable, you can configure +them to be logged to their own log model; this is done by subclassing the abstract ``wagtail.core.models.BaseLogEntry`` +model, and registering that model with the log registry's ``register_model`` method: + +.. code-block:: python + + from myapp.models import Sprocket, SprocketLogEntry + # here SprocketLogEntry is a subclass of BaseLogEntry + + @hooks.register('register_log_actions') + def sprocket_log_model(actions): + actions.register_model(Sprocket, SprocketLogEntry) diff --git a/docs/releases/2.15.rst b/docs/releases/2.15.rst index 615f29da0d..c473bfa5a1 100644 --- a/docs/releases/2.15.rst +++ b/docs/releases/2.15.rst @@ -141,3 +141,14 @@ should now be rewritten as: return _('Hello %(audience)s') % { 'audience': log_entry.data['audience'], } + + +``PageLogEntry.objects.log_action`` is deprecated +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Audit logging is now supported on all model types, not just pages, and so the ``PageLogEntry.objects.log_action`` +method for logging actions performed on pages is deprecated in favour of the general-purpose ``log`` function. Code that +calls ``PageLogEntry.objects.log_action`` should now import the ``log`` function from ``wagtail.core.log_actions`` and +call this instead (all arguments are unchanged). + +Additionally, for logging actions on non-Page models, it is generally no longer necessary to subclass ``BaseLogEntry``; see :ref:`audit_log` for further details.