.. _unpublishing: ============================== Un-publishing data ============================== In order to facilitate restoring erroneously removed items, each :term:`model` in the :term:`QMS` has a "publish" field. :term:`Un-publishing` item marks it as "deleted" for the end users. .. seealso:: :mod:`utils.unpublish` implemented in :task:`27238` .. note:: Unpublished items are still visible to :term:`staff` in :term:`django admin` panel. Un-publishing child items ========================= Un-publishing an item will cascade to its child items. For example, un-publishing a :term:`ward` means that all :term:`sessions ` and :term:`observations ` submitted to it are no longer accessible by users. Similarly, un-publishing an :term:`institution` or department will unpublish all related wards. This cascading logic applies to all relations set as :code:`on_delete=CASCADE`. All other relations are unaffected. For instance, :code:`on_delete=SET_NULL` will not set null until the item is physically deleted from the database. .. warning:: While all children of unpublished objects are automatically detected and unpublished, generic relations (:term:`issues `, comments) are more tricky, so to optimize the process, only some models will trigger un-publish on those, More details in :func:`unpublish_generic_relations`. In dashboards and settings --------------------------- Any action labelled as "remove" will unpublish the item and its child items. This action requires that user has the "delete" :term:`permission` even though the item is technically being modified rather than edited as it results in user losing access to the object as if it were deleted. The label "Remove" also indicates that the item is not being "deleted". .. figure:: img/unpublish-settings.png The **Remove** button unpublishes the edited item and its child items. In this case a :term:`ward` is being removed. This will also un-publish all rooms, but also any :term:`observations ` submitted to this ward. In :term:`django admin` ------------------------- **The "Unpublish" button is available besides "Delete" in every model that is published. It will give you a preview of related items about to be unpublished so you can review and confirm.** .. figure:: img/unpublish-admin-btn.png The "Unpublish" button in django admin is effectively the same as "Remove" is dashboards, but it will give you a chance to review related items before unpublishing .. figure:: img/unpublish-confirm.png The confirmation page lists and summarizes all object that will be affected by the unpublish action **Unpublishing in bulk by selecting items and choosing "Unpublish (including relations)" will result in items and their children being un-published** .. figure:: img/unpublish-relations.png The "Unpublish (including relations)" action will unpublish selected objects, including their child items Exceptions ^^^^^^^^^^^^ In django admin it is possible to unpublish a single object without propagating this change to child items **unpublishing item by un-ticking "publish" checkbox only affects the current item and *does not* propagate to child items** .. figure:: img/unpublish-admin-checkbox.png The checkbox can be used to un-publish the item without affecting any child items **The base "Unpublish" admin action will only unpublish selected objects without propagating change to relations** In Python code ------------------------------- Use :class:`~utils.unpublish.Unpublisher` class to unpublish object, propagate its removal to children, and log the action. .. code-block:: python u = Unpublisher(obj, user=user) u.unpublish(log_action=True, log_comment="Unpublished by user") .. seealso:: The :class:`~utils.unpublish.Unpublisher` class has more functionality. Visit its documentation and its main :meth:`~utils.unpublish.Unpublisher.unpublish` method for more details. Using command-line to update child objects =========================================== If objects have been unpublished, but their children have not, it may lead to inconsistent state and some unpredicted issues. Use the command below to ensure that children of all unpublished object are also unpublished: .. code-block:: shell # unpublish children of commonly used models ./manage.py propagate_unpublished # Unpublish children of specific models ./manage.py propagate_unpublished eguide auditform .. note:: This command runs non-atomically, so if it crashes or stops before completing, it will partially complete the process without rolling back changes. Restoring removed items ======================== **Undo removal** The proper way to restore (undo unpublish) items is to use :class:`~action_audit.models.UnpublishLogEntry` :url:`admin page ` and invoke the "Restore unpublished objects" action. The admin page shows exact date/time of removal and the user who did it along with the number of objects affected. .. figure:: img/unpublish-restore.png The restore action restores the object and its children **To re-publish individual items, you need to either:** * go to model's :term:`django admin` page, select multiple objects, and run "Publish" action * go through each item and publish it intedepndently by checking "published" .. figure:: img/unpublish-admin-checkbox.png The checkbox can be used to re-publish the item Logging unpublished items ============================ .. autoclass:: action_audit.models.UnpublishLogEntry :members: