有关于使用Python dict
with z3c.form
(加载&存储表单数据)。
然而,用于字典的z3c.form
datamanager
没有为其他类型或接口注册(参见参考文献),而注释通常使用类似PersistentDict
的东西。
该场景下如何使用DictionaryField
datamanager
?Ie。因此,在我的形式的getContent
方法,我只返回PersistentDict
注释。
嗯,不幸的是,似乎没有简单的解决方案来满足这个需求。我曾经在使用z3c形式的数据网格字段时遇到过同样的问题。
下面的指令解决了datagrid字段的问题,该字段是list
(PersistentList of 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
应该是你在表单模式中使用的字段名。
要实现数据网格字段,还有一些工作要做,但这可能对您的情况足够了。
请发表评论,或追溯,以便我可以提供进一步的帮助。如果有必要,我会添加更多的细节/解释;-)
答案很简单,只需注册下面的ZCML适配器:
<adapter
for="persistent.dict.PersistentDict zope.schema.interfaces.IField"
provides="z3c.form.interfaces.IDataManager"
factory="z3c.form.datamanager.DictionaryField"
/>
这样,下面的自定义表单就足以使用(PersistentDict
)注释来加载&存储表单数据:
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
警告不要为每个映射类型启用DictionaryField
,因此,例如,为表单存储创建PersistentDict
子类可能是明智的,而不是直接使用它。我向z3c提交了一个问题。表格,要求澄清警告。