1

Collective.z3c.datagridfield を使用してカスタムの Dexterity コンテンツ タイプを次のように定義しています。

class ILanguageRow(Interface):
    # Interface that defines a datagrid row.
    lang = schema.Choice(
        title=_(u'Language'), required=True, 
        source=my_languages,
        default=u'en',
    )

(...)

これは、http://plone.org/products/dexterity/documentation/manual/schema-driven-forms/customising-form-b​​ehaviour /vocabularies のように、語彙を返す関数です。

@grok.provider(IContextSourceBinder)
def languages(context):
    """
    Return a vocabulary of language codes and
    translated language names.
    """

    # z3c.form KSS inline validation hack
    if not ISiteRoot.providedBy(context):
        for item in getSite().aq_chain:
            if ISiteRoot.providedBy(item):
                context = item

    # retrieve the localized language names.
    request = getRequest()
    portal_state = getMultiAdapter((context, request), name=u'plone_portal_state')
    lang_items = portal_state.locale().displayNames.languages.items()

    # build the dictionary
    return SimpleVocabulary(
        [SimpleTerm(value=lcode, token=lcode, title=lname)\
          for lcode, lname in sorted(lang_items) if lcode in config.CV_LANGS]
    )

編集および追加フォーム内で、選択肢フィールドが正しく機能します。しかし、コンテンツを保存しようとすると:

TypeError: argument of type 'function' is not iterable
2011-07-08 13:37:40 ERROR Zope.SiteErrorLog 1310125060.840.103138625259 http://localhost:8081/Plone/++add++my.content.types.curriculum
Traceback (innermost last):
  Module ZPublisher.Publish, line 126, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 46, in call_object
  Module plone.z3cform.layout, line 70, in __call__
  Module plone.z3cform.layout, line 54, in update
  Module my.content.types.curriculum, line 356, in update
  Module plone.z3cform.fieldsets.extensible, line 59, in update
  Module plone.z3cform.patch, line 30, in GroupForm_update
  Module z3c.form.group, line 134, in update
  Module z3c.form.group, line 47, in update
  Module z3c.form.group, line 43, in updateWidgets
  Module z3c.form.field, line 275, in update
  Module z3c.form.browser.multi, line 61, in update
  Module z3c.form.browser.widget, line 70, in update
  Module z3c.form.widget, line 396, in update
  Module z3c.form.widget, line 88, in update
  Module z3c.form.widget, line 390, in set
  Module collective.z3cform.datagridfield.datagridfield, line 112, in updateWidgets
  Module collective.z3cform.datagridfield.datagridfield, line 90, in getWidget
  Module z3c.form.browser.widget, line 70, in update
  Module z3c.form.object, line 213, in update
  Module z3c.form.widget, line 88, in update
  Module collective.z3cform.datagridfield.datagridfield, line 216, in set
  Module z3c.form.object, line 229, in applyValue
  Module z3c.form.validator, line 67, in validate
  Module zope.schema._bootstrapfields, line 153, in validate
  Module zope.schema._field, line 325, in _validate
TypeError: argument of type 'function' is not iterable

なぜこうなった?

4

2 に答える 2

2

この方法で、カスタム語彙を名前付き語彙として提供することで問題を解決しました。

from Products.CMFCore.interfaces import ISiteRoot
from zope.component import getMultiAdapter
from zope.site.hooks import getSite
from zope.globalrequest import getRequest

from my.content import config

class LanguagesVocabulary(object):

    grok.implements(IVocabularyFactory)

    def __call__(self, context):
        # z3c.form KSS inline validation hack
        if not ISiteRoot.providedBy(context):
            for item in getSite().aq_chain:
                if ISiteRoot.providedBy(item):
                    context = item

        # retrieve the localized language names.
        request = getRequest()
        portal_state = getMultiAdapter((context, request), name=u'plone_portal_state')
        lang_items = portal_state.locale().displayNames.languages.items()

        # build the dictionary
        terms = [SimpleTerm(value=lcode, token=lcode, title=lname)\
          for lcode, lname in sorted(lang_items) if lcode in config.CV_LANGS]

        return SimpleVocabulary(terms)

grok.global_utility(LanguagesVocabulary, name=u"my.content.LanguagesVocabulary")

および私の器用さのコンテンツ タイプ スキーマで:

class ILanguageRow(Interface):
    # Interface that defines a datagrid row.
    lang = schema.Choice(
        title=_(u'Language'), required=True, 
        vocabulary=u"my.content.LanguagesVocabulary",
    )

このように動作します。

于 2011-07-08T14:16:46.667 に答える
2

これは、フィールドがバインドされていないか、コンテキストが欠落している場合に発生します。通常、検証は「バインドされた」フィールド ( bound = field.bind(context)) に対して行われるため、文脈認識語彙をこの文脈の静的語彙に変えることができます。これが行われなかった場合でも、(コンテキストで呼び出されない) 関数になります。

これがどこでうまくいかないかを特定するための datagrid ウィジェットのセットアップに精通していませんが、オンザフライでウィジェットを生成しているようで、これらのフィールドを正しくバインドしていないと思われます。DataGridField.getWidgetモジュールのメソッドを見collective.z3cform.datagridfield.datagridfieldて、デバッガーで何が起こっているのかを把握するか、パッケージの作成者にバグを報告してください。

于 2011-07-08T13:29:06.857 に答える