移动Plone页面导致“在索引中已经存在一个不同的具有值的文档”错误
在我的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(),页面仍然会被旧的位置和新位置索引。因此上述错误。我怎样才能防止这种情况发生。
我认为这是因为你试图移动一个未完全创建的对象。
您可能想要更改事件处理程序的逻辑或将其注册为IObjectCreatedEvent,否则您将以循环结束。
无论何时将对象添加到容器中,都会调用IObjectAddedEvent,并且在移动它时也会发生这种情况。
据我了解事件的文档http://docs.plone.org/external/plone.app.dexterity /docs/advanced/event-handlers.html IObjectCreatedEvent在IObjectAddedEvent之前被触发。该文件建议使用后者。所以我认为这个对象应该完全创建。我想到了可能的循环,我试图通过比较标题的if语句来阻止它发生。 – Waynebird
你是对的,随时考虑这个答案错了。 – alepisa
该文档说“使用IObjectAddedEvent通常更容易”,因为在将对象添加到容器之前会触发IObjectCreatedEvent。然而,alepisa是正确的,你需要采取一个,因为另一个也被解雇时,粘贴一个对象。 –
它记住了我在执行相同事务脚本中的剪切/粘贴时可能遇到的问题。尝试在两个操作之间执行“transaction.savepoint”(或者完全提交) –