2017-01-05 26 views
2

在我的Plone实例中,我希望每个新创建的页面在创建之后移动到它自己的文件夹中。该文件夹应该与该页面具有相同的标题和说明。所以我写了这个功能zope.lifecycleevent.interfaces.IObjectAddedEvent的事件处理程序:移动Plone页面导致“在索引中已经存在一个不同的具有值的文档”错误

def notifyDocumentIsAdded(document, event): 
portal = api.portal.get() 
context = aq_inner(document) 
folder = aq_parent(context) 
if getattr(document,"title") != getattr(folder,"title"): 
    newfolder = api.content.create(
      type='Folder', 
      title=getattr(document,"title"), 
      container=folder, 
      description=getattr(document,"description")) 
    api.content.move(source=document,target=newfolder,safe_id=True) 

这工作,直到我想要的只是增加了新的一页移动到新的文件夹中的最后一行。我得到

ERROR Products.ZCatalog A different document with value 'c31f15e4923e4f2683dedc829d2f773d' already exists in the index.' 

具有该值的文档是什么意思?这是一个ID的冲突吗?或者移动触发事件的对象是否是一个问题?

更新: 使用Python调试器现在我更好地了解企业的​​实际问题后: 页面正确地移动,尽管我的上述声明。问题是:在我的处理程序执行后,页面将被具有过时位置的目录索引,而它被我的处理程序移动。即使在移动之后有一个transaction.commit(),页面仍然会被旧的位置和新位置索引。因此上述错误。我怎样才能防止这种情况发生。

+0

它记住了我在执行相同事务脚本中的剪切/粘贴时可能遇到的问题。尝试在两个操作之间执行“transaction.savepoint”(或者完全提交) –

回答

2

我认为这是因为你试图移动一个未完全创建的对象。

您可能想要更改事件处理程序的逻辑或将其注册为IObjectCreatedEvent,否则您将以循环结束。

无论何时将对象添加到容器中,都会调用IObjectAddedEvent,并且在移动它时也会发生这种情况。

+0

据我了解事件的文档http://docs.plone.org/external/plone.app.dexterity /docs/advanced/event-handlers.html IObjectCreatedEvent在IObjectAddedEvent之前被触发。该文件建议使用后者。所以我认为这个对象应该完全创建。我想到了可能的循环,我试图通过比较标题的if语句来阻止它发生。 – Waynebird

+0

你是对的,随时考虑这个答案错了​​。 – alepisa

+0

该文档说“使用IObjectAddedEvent通常更容易”,因为在将对象添加到容器之前会触发IObjectCreatedEvent。然而,alepisa是正确的,你需要采取一个,因为另一个也被解雇时,粘贴一个对象。 –

相关问题