敏捷对象由一个可枚举的模式定义:
from zope.interface.interfaces import IMethod
for name, desc in IYourDexteritySchema.namesAndDescriptions():
value = getattr(yourDexterityInstance, name)
if IMethod.providedBy(desc):
# It's a method, call it
value = value()
Run Code Online (Sandbox Code Playgroud)
在这里,我使用该.namesAndDescriptions()
方法,但如果您的架构上没有任何方法,您也可以将该接口用作迭代器:
for name in IYourDexteritySchema:
value = getattr(yourDexterityInstance, name)
Run Code Online (Sandbox Code Playgroud)
最后但并非最不重要的是,zope.schema
有一个名为的实用程序方法getFieldsInOrder
将过滤zope.schema
接口中的字段; 上面的方法还列出了方法和非模式属性,getFieldsInOrder
只列出了zope.schema
特定的属性类型:
from zope.schema import getFieldsInOrder
for name, field in getFieldsInOrder(IYourDexteritySchema):
value = getattr(yourDexterityInstance, name)
Run Code Online (Sandbox Code Playgroud)
如果您通过Web定义了架构,则可能不知道如何查找类型的界面.您还可以通过工厂类型信息或简称FTI检索架构界面:
from plone.dexterity.interfaces import IDexterityFTI
from zope.component import getUtility
schema = getUtility(IDexterityFTI, name='your.dexterity.type').lookupSchema()
Run Code Online (Sandbox Code Playgroud)
schema
现在哪里有你的界面.
小智 6
正如大卫所指出的那样,我无法找到一种方法来枚举来自行为的字段.
因此,深入了解plone.dexterity,在utils.getAdditionalSchemata函数中,我发现这种方式可以大致解决问题:
from zope.schema import getFieldsInOrder
from plone.behavior.interfaces import IBehaviorAssignable
behavior_assignable = IBehaviorAssignable(context)
if behavior_assignable:
behaviors = behavior_assignable.enumerateBehaviors()
for behavior in behaviors:
for k,v in getFieldsInOrder(behavior.interface):
# ...
Run Code Online (Sandbox Code Playgroud)
我找到了一种方法来做到这一点。由于敏捷方案各不相同,我无法直接使用克里斯托夫的建议。但这现在有效
for key, value in getFieldsInOrder(obj.getTypeInfo().lookupSchema()):
value = getattr(getattr(obj, key), 'output', getattr(obj, key))
Run Code Online (Sandbox Code Playgroud)