From 3fbcae4ca9aefd4acb69b396a9092619e3d6ba61 Mon Sep 17 00:00:00 2001 From: Roel Bruggink Date: Tue, 3 Feb 2015 23:32:36 +0100 Subject: [PATCH] Support a list of objects in content.delete Dont. Just use 'delete' Be explicit --- docs/CHANGES.rst | 3 +++ docs/content.rst | 22 +++++++++++++++++++++- src/plone/api/content.py | 17 ++++++++++++----- src/plone/api/tests/test_content.py | 12 ++++++++++++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/docs/CHANGES.rst b/docs/CHANGES.rst index e271f86d..9962bdd7 100644 --- a/docs/CHANGES.rst +++ b/docs/CHANGES.rst @@ -4,6 +4,9 @@ Changelog 1.3.3 (unreleased) ------------------ +- Allow deleting multiple objects. Fixes #198 + [jaroel] + - Fixed `make docs`. [jaroel] diff --git a/docs/content.rst b/docs/content.rst index 3bab4148..183644de 100644 --- a/docs/content.rst +++ b/docs/content.rst @@ -97,7 +97,7 @@ The following operations will get objects from the stucture above, including usi # moreover, you can access content by its UID uid = about['team'].UID() team = api.content.get(UID=uid) - + # returns None if UID cannot be found in catalog not_found = api.content.get(UID='notfound') @@ -265,6 +265,26 @@ To delete a content object, pass the object to the :meth:`api.content.delete` me self.assertFalse(portal.get('copy_of_training')) +To delete multiple content objects, pass the objects to the :meth:`api.content.delete` method: + +.. invisible-code-block: python + + api.content.copy(source=portal['training'], target=portal, safe_id=True) + api.content.copy(source=portal['events']['training'], target=portal['events'], safe_id=True) + +.. code-block:: python + + from plone import api + portal = api.portal.get() + data = [portal['copy_of_training'], portal['events']['copy_of_training'], ] + api.content.delete(objects=data) + +.. invisible-code-block: python + + self.assertFalse(portal.get('copy_of_training')) + self.assertFalse(portal.events.get('copy_of_training')) + + .. _content_manipulation_with_safe_id_option: Content manipulation with the `safe_id` option diff --git a/src/plone/api/content.py b/src/plone/api/content.py index 4ad8a3f2..31a59fe5 100644 --- a/src/plone/api/content.py +++ b/src/plone/api/content.py @@ -254,17 +254,24 @@ def copy(source=None, target=None, id=None, safe_id=False): return target[new_id] -@required_parameters('obj') -def delete(obj=None): - """Delete the object. +@at_least_one_of('obj', 'objects') +def delete(obj=None, objects=None): + """Delete the object(s). - :param obj: [required] Object that we want to delete. + :param obj: Object that we want to delete. :type obj: Content object + :param objects: Objects that we want to delete. + :type objects: List of content objects :raises: ValueError :Example: :ref:`content_delete_example` """ - obj.aq_parent.manage_delObjects([obj.getId()]) + if obj is not None: + obj.aq_parent.manage_delObjects([obj.getId()]) + else: + # The objects may have different parents + for obj in objects: + delete(obj=obj) @required_parameters('obj') diff --git a/src/plone/api/tests/test_content.py b/src/plone/api/tests/test_content.py index 217e5b15..13745724 100644 --- a/src/plone/api/tests/test_content.py +++ b/src/plone/api/tests/test_content.py @@ -582,6 +582,18 @@ def test_delete(self): api.content.delete(self.contact) assert 'contact' not in container['about'].keys() + def test_delete_multiple(self): + """Test deleting multiple content items.""" + + container = self.portal + api.content.copy(source=container['about'], target=container) + api.content.copy(source=container['about'], target=container['events']) + + api.content.delete(objects=[container['copy_of_about'], + container['events']['about']]) + assert 'copy_of_about' not in container + assert 'about' not in container['events'] + def test_get_state(self): """Test retrieving the workflow state of a content item."""