Wrong Widget/Field conversion in datagrid

I have just run into two seemingly related situations where values in a datagrid result in Plone errors.

Situation 1. a date field in the nested schema leads to

Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 167, in transaction_pubevents
  Module ZPublisher.WSGIPublisher, line 376, in publish_module
  Module ZPublisher.WSGIPublisher, line 271, in publish
  Module ZPublisher.mapply, line 85, in mapply
  Module ZPublisher.WSGIPublisher, line 68, in call_object
  Module pnz.erpediem.core.browser.customer, line 50, in __call__
  Module plone.autoform.view, line 40, in __call__
  Module plone.autoform.view, line 62, in _update
  Module z3c.form.group, line 52, in update
  Module z3c.form.group, line 48, in updateWidgets
  Module z3c.form.field, line 274, 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 510, in update
  Module Products.CMFPlone.patches.z3c_form, line 46, in _wrapped
  Module z3c.form.widget, line 132, in update
  Module z3c.form.widget, line 505, in value
  Module collective.z3cform.datagridfield.datagridfield, line 149, in updateWidgets
  Module z3c.form.widget, line 447, in updateWidgets
  Module z3c.form.widget, line 396, in applyValue
  Module z3c.form.object, line 119, in toFieldValue
  Module plone.app.z3cform.converters, line 69, in toFieldValue
AttributeError: 'datetime.date' object has no attribute 'split'

Situation 2. looking up a token in a vocabulary leads to

Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 167, in transaction_pubevents
  Module ZPublisher.WSGIPublisher, line 376, in publish_module
  Module ZPublisher.WSGIPublisher, line 271, in publish
  Module ZPublisher.mapply, line 85, in mapply
  Module ZPublisher.WSGIPublisher, line 68, in call_object
  Module pnz.erpediem.core.browser.remadv, line 48, in __call__
  Module plone.autoform.view, line 40, in __call__
  Module plone.autoform.view, line 62, in _update
  Module z3c.form.group, line 52, in update
  Module z3c.form.group, line 48, in updateWidgets
  Module z3c.form.field, line 274, 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 510, in update
  Module Products.CMFPlone.patches.z3c_form, line 46, in _wrapped
  Module z3c.form.widget, line 132, in update
  Module z3c.form.widget, line 505, in value
  Module collective.z3cform.datagridfield.datagridfield, line 149, in updateWidgets
  Module z3c.form.widget, line 447, in updateWidgets
  Module z3c.form.widget, line 396, in applyValue
  Module z3c.form.object, line 119, in toFieldValue
  Module z3c.form.converter, line 306, in toFieldValue
  Module z3c.form.term, line 41, in getValue
  Module z3c.form.term, line 188, in getTermByToken
LookupError: 3

In the first case, I originally chalked it up to my own fault when reading

and made my object return a string.

However, in the second case, the term lookup fails to find '3' - rather than '380' (for an EDI Invoice)

I dove into the z3c.form rabbithole... By commenting out and adding fvalue=value in

My page displays as intended. Both the date field and the vocabulary lookup now work.

But this is of course not a viable solution...

I could really use some assistance from the community to find the source of the problem. Please help?

Norbert

Just to add: I tried both with and without a custom converter, following collective.z3cform.datagridfield/editform_object.py at master · collective/collective.z3cform.datagridfield · GitHub

My converter is registered but does not kick in. e.g.

     <adapter
        factory=".adapters.customer.CustomerOrdersConverter"
        />  

The schema

class CustomerOrdersField(schema.List):
    """We need to have a unique class for the field list so that we
    can apply a custom adapter."""
    pass

@provider(IFormFieldProvider)
class ICustomer(model.Schema):

    """ Form schema for Customer objects """

    customer_number = schema.TextLine(
        title = _(u'Customer Number'),
        required=True,
    )
    recent_orders = CustomerOrdersField(
        title=_(
            'recent_orders_title',
            default = u'Recent Orders',
        ),
        value_type=schema.Object(
            title=_(
                'value_type_title',
                default=u'Table',
            ),
            schema=IOrderHeading,
        ),
        default=[],
        required=False,
    )
    directives.widget('recent_orders', DataGridFieldWidgetFactory)

The converter:

@adapter(CustomerOrdersField, DataGridFieldObjectWidget)
@implementer(IDataConverter)
class CustomerOrdersConverter(BaseDataConverter):
    """Convert between the SQLA InstrumentedList object and the widget.
    """

    def toWidgetValue(self, value):
        """Simply pass the data through with no change"""
        rv = list()
        for row in value:
            
            log.info('converting to widget value')

            d = dict()
            for name, f in getFieldsInOrder(IOrderHeading):
                d[name] = getattr(row, name)
            rv.append(d)
        return rv

    def toFieldValue(self, value):
        rv = Order()
        for row in value:
            
            log.info('converting to field value')
            
            d = dict()
            for name, f in getFieldsInOrder(IOrderHeading):
                if row.get(name, NO_VALUE) != NO_VALUE:
                    d[name] = row.get(name)
            rv.append(Order(**d))
        return rv

This can be reproduced with a simple ttw dexterity type with a dg field that contains a date...