有documentation使用Python dict
with z3c.form
(加载和存储表单数据)。
但是,用于dicts的z3c.form
datamanager
未注册其他类型或接口(请参阅reference),而注释通常使用类似PersistentDict
的内容。
如何在此方案中使用DictionaryField
datamanager
? IE浏览器。所以在我的表单的getContent
方法中,我只返回PersistentDict
注释。
答案 0 :(得分:2)
嗯,不幸的是,这个要求似乎没有简单的解决方案。 我曾经在z3c表单中使用datagrid字段遇到同样的问题。
以下指令解决了datagrid字段的问题,即list
(PersistentList dicts
(PersistentMappings)。
我想你可能会根据你的情况调整这个解决方案。
首先,您需要将以下代码添加到getContent
方法:
from plone.directives import form
class MyForm(form.SchemaEditForm):
schema = IMyFormSchema
ignoreContext = False
def getContent(self):
annotations = IAnnotations(self.context)
if ANNOTATION_KEY not in annotations:
annotations[ANNOTATION_KEY] = PersistentMapping()
return YourStorageConfig(annotations[ANNOTATION_KEY])
重要说明:我将注释存储包装起来以满足z3c表单的get / set行为。检查以下YourStorageConfig
实现,您将看到原因: - )。
class YourStorageConfig(object):
implements(IMyFormSchema)
def __init__(self, storage):
self.storage = storage
def __getattr__(self, name):
if name == 'storage':
return object.__getattr__(self, name)
value = self.storage.get(name)
return value
def __setattr__(self, name, value):
if name == 'storage':
return object.__setattr__(self, name, value)
if name == 'yourfieldname':
self.storage[name] = PersistentList(map(PersistentMapping, value))
return
raise AttributeError(name)
yourfieldname
应该是您在表单架构中使用的字段名称。
要实现数据网格字段,还有一些工作要做,但这对您的情况来说已经足够了。
请发表评论或追溯,以便我提供进一步的帮助。如有必要,我会添加更多细节/解释; - )
答案 1 :(得分:1)
事实证明,答案就像下面的ZCML适配器注册一样简单:
<adapter
for="persistent.dict.PersistentDict zope.schema.interfaces.IField"
provides="z3c.form.interfaces.IDataManager"
factory="z3c.form.datamanager.DictionaryField"
/>
通过这种方式,表单的以下自定义足以使用(PersistentDict
)注释来加载&amp;存储表单数据:
def getContent(self):
"return the object the form will manipulate (load from & store to)"
annotations = IAnnotations(self.context)
return annotations[SOME_ANNOTATIONS_KEY_HERE]
这假设PersistentDict
之前已存储annotations[SOME_ANNOTATIONS_KEY_HERE]
- 否则上述代码将导致KeyError
。更改高于getContent
可能是个好主意,这样如果注释尚不存在,则会使用一些默认值创建和初始化。
最后,请注意,出于某种原因,z3c.form
warns反对为每种映射类型启用DictionaryField
,因此对于表单存储的子类PersistentDict
可能是谨慎的而不是直接使用它。我向z3c.form提交了an issue,要求澄清该警告。