当存在两个相邻的相同ID时,unrestrictedTraverse会获取错误的对象

时间:2011-07-07 22:59:55

标签: plone

我有:

try:
    path1 = /Plone/s/a
    path2 = 2011/07/07
    #The path to traverse becomes /Plone/s/a/2011/07/07/. From
    #Plone to last 07, they are normal Folders.
    ob = self.portal.unrestrictedTraverse('%s/%s/' % (path1, path2))
    print ob
except AtributeError:
    #do something
    pass

/ Plone / s / a / 2011/07/07 / 不存在。 / Plone / s / a / 2011/07 / 存在。上面的代码应该给出AtributeError,但我得到 / Plone / s / a / 2011/07 / 对象。它打印:

<ATFolder at /Plone/s/a/2011/07 used for /Plone/s/a/2011/07>

我不想从遍历得到“类似”的结果,这是错误的。我需要特别 / Plone / s / a / 2011/07/07 / 。如果它不存在,我想抓住异常。

我可以使用哪些其他方法来查看是否存在完全位于 / Plone / s / a / 2011/07/07 / 的对象,而不是足够接近 / Plone的/ S / A / 2011/07 /

1 个答案:

答案 0 :(得分:4)

你遇到了收购。

您想要获取'07'文件夹的'07'元素/属性/属性。但是最后一个没有具有该id的子对象。因此,由于获取,现有的'07'文件夹询问其父元素是否有一个具有上述id的子对象,当然,'2011'文件夹中有该元素,'07'是你坐的

这是对收购如何运作的粗略解释。

另一个例子是这个URL: http://plone.org/news/news/news/news/news/events

“events”文件夹在“news”文件夹中并不真正生活。并且所有那些“新闻”文件夹并不存在,但是至少有一个“新闻”文件夹存在于plone.org根目录中,虽然它没有'events'文件夹,但是它的父文件(plone.org)确实。

这里有一些参考资料:

如果您想确保元素/属性/属性确实是父元素的一部分,您应该使用aq_base中的Acquisition

from Acquisition import aq_base

plone = aq_base(self.portal.Plone)
s = aq_base(getattr(plone, 's'))
a = aq_base(getattr(s, 'a'))
year = aq_base(getattr(a, '2011'))
month = aq_base(getattr(year, '07'))
day = aq_base(getattr(month, '07'))

aq_base从元素中剥离采集链,因此不会使用任何采集来获取其元素。