我们有一个基于敏捷的内容类型,必须从其父级继承字段的默认值。我们使用以下内容:
在模型中:
<model xmlns="http://namespaces.plone.org/supermodel/schema"
xmlns:indexer="http://namespaces.plone.org/supermodel/indexer"
xmlns:form="http://namespaces.plone.org/supermodel/form">
<schema>
...
<field name="subjects" type="zope.schema.Tuple" indexer:searchable="true">
...
<defaultFactory>my.package.content.default_subjects</defaultFactory>
...
</field>
</schema>
</model>
工厂宣布如下:
from zope.schema.interfaces import IContextAwareDefaultFactory
...
@provider(IContextAwareDefaultFactory)
def default_subjects(context):
return getattr(context, 'subjects', ())
这在运行实例时工作正常:
(Pdb) context
<MyType at /Plone/folder>
(Pdb) type(context)
<type 'Acquisition.ImplicitAcquisitionWrapper'>
但是因为上下文没有被包装而运行测试时失败了:
(Pdb) context
<MyType at test>
(Pdb) type(context)
<class 'my.package.content.MyType'>
我该如何解决这个问题?
答案 0 :(得分:1)
你正在做的一切正确。 在代码中,您尝试访问这样的主题:
>>> object.subjects
从未设置subjects
时,Dexterity的__getattr__
实现开始工作。缺少属性的__getattr__
魔法由Python实现。它以某种方式失去了采集包装器。
在取消采集包装后,aq_parent和父都不会继续工作。
在我的测试中,我能够通过调用
>>> object.__getattr__('subjects')
但这并不令人满意。
在视图代码中,您没有此问题,因为视图根本不会通过object.subjects
访问该属性,因此获取上下文永远不会丢失。
我在这里完成了我的分析,但是我在plone.dexterity的bug报告中注意到了我的发现。也许你想在那里提供一个最小的测试: https://github.com/plone/plone.dexterity/issues/53