4

有关于使用 Python的文档dict with z3c.form(加载和存储表单数据)。

但是,z3c.form datamanager用于 dicts 没有为其他类型或接口注册(请参阅参考资料),而注解通常使用类似PersistentDict.

DictionaryField datamanager在这种情况下如何使用?IE。所以在我的表单getContent方法中,我只返回PersistentDict注释。

4

2 回答 2

2

好吧,不幸的是,这个要求似乎没有简单的解决方案。我曾经在 z3c 表单中使用 datagrid 字段时遇到过同样的问题。

下面的指令解决了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 表单的获取/设置行为。检查以下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应该是您在表单架构中使用的字段名称。

要实现数据网格字段,还有一些工作要做,但这对于您的情况可能已经足够了。

请发表评论或回溯,以便我提供进一步的帮助。如有必要,我将添加更多详细信息/解释;-)

于 2015-10-23T15:38:06.107 回答
1

事实证明,答案就像下面的 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]

这是假设 aPersistentDict先前已存储在annotations[SOME_ANNOTATIONS_KEY_HERE]- 否则上面的代码将导致KeyError. 在上面进行更改可能是一个好主意,getContent以便如果注释尚不存在,则使用一些默认值创建和初始化它。

最后,请注意,出于某种原因,z3c.form 警告不要启用DictionaryField每种映射类型,因此可能谨慎地PersistentDict为表单存储进行子类化,而不是直接使用它。我向 z3c.form 提交了一个问题,要求澄清该警告。

于 2015-10-24T16:03:05.873 回答