简体   繁体   English

如何在z3c.form的DictionaryField中使用注释

[英]How to use annotations with z3c.form's DictionaryField

There is documentation on using Python dict with z3c.form (loading & storing form data). 有关于使用Python dict with z3c.form (加载和存储表单数据)的文档

However, the z3c.form datamanager used for dicts is not registered for other types or interfaces (see reference ), whereas annotations typically use something like PersistentDict . 然而, z3c.form datamanager用于http://stardict.sourceforge.net/Dictionaries.php下载未注册的其它类型或接口(见参考 ),而注释通常使用类似PersistentDict

How can I use the DictionaryField datamanager in this scenario? 我如何使用DictionaryField datamanager在这种情况下? Ie. IE浏览器。 so that in my form's getContent method I merely return the PersistentDict annotation. 所以在我的表单的getContent方法中我只返回PersistentDict注释。

Well, unfortunately there seems no simple solution for this requirement. 好吧,不幸的是,这个要求似乎没有简单的解决方案。 I once faced the same problem using the datagrid field in a z3c form. 我曾经在z3c表单中使用datagrid字段遇到同样的问题。

The following instruction solves the problem for the datagrid field, which is a list (PersistentList of dicts (PersistentMappings). 以下指令解决了datagrid字段的问题,该字段是一个listdicts of dicts (PersistentMappings))。

I guess you may adapt this solution for your case. 我想你可以根据你的情况调整这个解决方案。

First you need to add the following code to the getContent method: 首先,您需要将以下代码添加到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])

Important note: I wrap the annotation storage to satisfy the get/set behavior of the z3c form. 重要说明:我包装注释存储以满足z3c表单的get / set行为。 Check the following YourStorageConfig implementation and you will see why :-). 检查以下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 should be the field name you are using in the form schema. yourfieldname应该是您在表单架构中使用的字段名称。

To implement the a datagrid field, there is some more work to do, but this may be enough for your case. 要实现数据网格字段,还有一些工作要做,但这对您的情况来说已经足够了。

Please post comments, or tracebacks, so I can provide further help. 请发表评论或追溯,以便我可以提供进一步的帮助。 I'll gonna add more details/explanation if necessary ;-) 如有必要,我会添加更多细节/解释;-)

It turns out the answer is as easy as the following ZCML adapter registration: 事实证明,答案就像下面的ZCML适配器注册一样简单:

<adapter
  for="persistent.dict.PersistentDict zope.schema.interfaces.IField"
  provides="z3c.form.interfaces.IDataManager"
  factory="z3c.form.datamanager.DictionaryField"
 />

With that, the following customization of a form is sufficient to use ( PersistentDict ) annotations for loading & storing form data: 有了这个,表单的以下自定义就足以使用( 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]

This is assuming that a PersistentDict has been previously stored at annotations[SOME_ANNOTATIONS_KEY_HERE] - otherwise the above code will result in KeyError . 这是假设一个PersistentDict先前已存储在annotations[SOME_ANNOTATIONS_KEY_HERE] -否则,上面的代码将导致KeyError It would probably be a good idea to change above getContent so that if the annotation does not yet exist, it is created and initialized with some default values. 更改上面的getContent可能是一个好主意,这样如果注释尚不存在,则会创建并使用一些默认值进行初始化。

Finally, note that for some reason, z3c.form warns against enabling DictionaryField for every mapping type, so it may be prudent to for example subclass PersistentDict for form storage, rather than use it directly. 最后,请注意,由于某种原因, z3c.form 警告不要为每种映射类型启用DictionaryField ,因此例如对于表单存储子类PersistentDict可能是谨慎的,而不是直接使用它。 I submitted an issue to z3c.form asking for clarification of that warning. 我向z3c.form提交了一个问题 ,要求澄清该警告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM