Avoid deletion of an object (using IObjectWillBeRemovedEvent) and do a redirect to a custom view/template?

StackOverflow https://stackoverflow.com/questions/7098013

  •  23-12-2020
  •  | 
  •  

Question

I would like to abort the deletion of an object (A custom Content-Type), and redirect to a page (a view) that sets the workflow to a custom state named Unavailable, shows a message to the user "You succesfully deleted the object!". The object will still be on ZODB, but for some groups it'll simply not be seen, as if it was really deleted.

I can do a raise in a subscriber using IObjectWillBeRemovedEvent, but trying to use raise zExceptions.Redirect("url") doesn't work. The raise call avoids the deletion, but a message "The object could not be deleted" is shown instead of the redirection.

Anyone has a solution to this scenario?

Was it helpful?

Solution

As you can see Plone / Zope 2 object management is messy (yes, I am willing to burn karma just to say this). You need to override delete action in the user interface level, not on the object level.

Try to figure out how to customize delete actions in Plone user interface.

  • Make sure the default Delete actions is no longer visible and available (e.g. set higher needed permission for it e.g. cmf.ManagePortal)

  • Create another Delete action which goes according to your specialized workflow

I believe Delete can be configured from portal_actions, but there might be separate cases for deleting one object (Actions menu) and deleting multiple objects (folder_contents).

OTHER TIPS

You need REQUEST.response.redirect("url"). I'm pretty sure that zExceptions.Redirect is the way that Zope internally handles response.redirect() calls. Be sure you still raise another exception after calling redirect() so that the transaction is aborte.

That said, this sure seems like the wrong way to accomplish this. For one thing, you'll do at least double indexing, which is done before the transaction aborts. Catalog indexing is the most expensive part of processing a request that modifies content so this creates wasteful load on your server.

Events are for doing additional stuff which is only tangentially related to the event. What you want is to fundamentally change what happens when someone deletes. Maybe you should patch/override the underlying deletion method on the container objects (folders?) to do your worklfow transition.

You could raise a OFS.ObjectManager.BeforeDeleteException in the event handler to stop the deletion. If you raise a LinkIntegrityNotificationException you get redirected to Plones nice Link intergrity page.

from OFS.interfaces import IObjectWillBeRemovedEvent
from plone.app.linkintegrity.exceptions import LinkIntegrityNotificationException
import grok

@grok.subscribe(ICSRDocument, IObjectWillBeRemovedEvent)
def document_willbemoved(doc, event):
    raise LinkIntegrityNotificationException(doc)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top