词汇表不能用于collective.z3cform.datagridfield的子对象模式,因为上下文是NO_VALUE

时间:2013-07-12 04:50:46

标签: plone z3c.form

我正在处理使用datagridfield的内容类型。 在子对象中,我有一个带有自定义词汇表的选择字段。

数据网格之外的词汇表工作(如果我直接在内容类型的模式中使用它)。但是当我将它添加到子对象时,它不再起作用了。

查看调试说明,我看到vocabluary的上下文是NO_VALUE。

任何提示/方向使其有效?

这是最简单的架构(我认为):

# Import 
from zope import schema
from zope.interface import Interface

from plone.directives import form
from collective.z3cform.datagridfield import DataGridFieldFactory, DictRow

# The container
class IMenu(Interface):
    dishes = schema.List(value_type=schema.TextLine())

# The vocabulary 
@grok.provider(IContextSourceBinder)
def getDishes(context):
    terms = [SimpleVocabulary.createTerm(dish, dish, dish) for dish in context.dishes]
    return SimpleVocabulary(terms)

# The object line
class IOrderLine(Interface):
    dish = schema.Choice(source=getDishes)
    quantity = schema.Int()

# The object
class IOrder(Interface):
    form.widget(dishes=DataGridFieldFactory)
    dishes = schema.List(value_type=DictRow(schema=IOrderLine))

现在我注册Menu,Order as dexterity content type,添加一个菜单并尝试在其中添加一个订单,我在订单添加视图上收到错误,这是追溯:

Traceback (innermost last):
  Module ZPublisher.Publish, line 126, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module Products.PDBDebugMode.runcall, line 70, in pdb_runcall
  Module ZPublisher.Publish, line 46, in call_object
  Module plone.z3cform.layout, line 66, in __call__
  Module plone.z3cform.layout, line 50, in update
  Module plone.dexterity.browser.add, line 112, 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 128, in update
  Module z3c.form.form, line 134, in updateWidgets
  Module z3c.form.field, line 277, in update
  Module z3c.form.browser.multi, line 63, in update
  Module z3c.form.browser.widget, line 171, in update
  Module z3c.form.widget, line 477, in update
  Module collective.z3cform.datagridfield.datagridfield, line 107, in updateWidgets
  Module collective.z3cform.datagridfield.datagridfield, line 91, in getWidget
  Module z3c.form.browser.widget, line 171, in update
  Module z3c.form.object, line 217, in update
  Module z3c.form.object, line 208, in updateWidgets
  Module z3c.form.object, line 87, in update
  Module plone.z3cform.patch, line 21, in BaseForm_update
  Module z3c.form.form, line 150, in update
  Module z3c.form.form, line 134, in updateWidgets
  Module z3c.form.field, line 277, in update
  Module z3c.form.browser.select, line 51, in update
  Module z3c.form.browser.widget, line 171, in update
  Module z3c.form.widget, line 220, in update
  Module z3c.form.widget, line 214, in updateTerms
  Module zope.component._api, line 107, in getMultiAdapter
  Module zope.component._api, line 120, in queryMultiAdapter
  Module zope.component.registry, line 238, in queryMultiAdapter
  Module zope.interface.adapter, line 532, in queryMultiAdapter
  Module z3c.form.term, line 96, in ChoiceTerms
  Module zope.schema._field, line 349, in bind
  Module waga.game.core.content.interfaces, line 202, in getDishes
AttributeError: 'NO_VALUE' object has no attribute 'dishes'
> /home/quyetnd/Projects/waga.game.core/src/waga/game/core/content/interfaces.py(202)getDishes()
-> terms = [SimpleVocabulary.createTerm(dish, dish, dish) for dish in context.dishes]

上下文对象是一个实例。

1 个答案:

答案 0 :(得分:3)

这是z3c.form的限制(至少某些版本,我认为它已在新版本中得到修复)。

我在词汇源函数中的丑陋解决方法:

 if not context:
      context = getSite()
      if not context:
           # Form is rendered from console without HTTP request traversing, etc.
           # and thread local site variable is not set
           raise RuntimeError("Oh snap. Beer time.")

 ...

http://developer.plone.org/serving/traversing.html#using-getsite