collective / collective.z3cform.datagridfield

Datagrid Field for z3c.forms
https://pypi.org/project/collective.z3cform.datagridfield/
8 stars 28 forks source link

RelatedItemsFieldWidget/RelationList: TypeError when I try to save #137

Closed Arkusm closed 1 year ago

Arkusm commented 2 years ago

Plone: classic 6.0.0b3 datagridfield branch: master

RelationList and RelatedItemsFieldWidget work great when I edit an object. I need the RelatedItemsFieldWidget because it is the only Widget that supports ordering selected items. But when I try to save there is an error:

2022-10-24 09:44:51,602 ERROR   [Zope.SiteErrorLog:35][waitress-2] TypeError: http://localhost:7080/plone/welcome-page/@@edit
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 plone.z3cform.layout, line 63, in __call__
  Module plone.z3cform.layout, line 47, in update
  Module plone.dexterity.browser.edit, line 53, in update
  Module plone.z3cform.fieldsets.extensible, line 65, in update
  Module plone.z3cform.patch, line 30, in GroupForm_update
  Module z3c.form.group, line 132, in update
  Module z3c.form.form, line 136, 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 509, in update
  Module Products.CMFPlone.patches.z3c_form, line 46, in _wrapped
  Module z3c.form.widget, line 88, in update
  Module z3c.form.widget, line 530, in extract
  Module collective.z3cform.datagridfield.datagridfield, line 127, in getWidget
  Module z3c.form.browser.widget, line 171, in update
  Module z3c.form.object, line 295, in update
  Module Products.CMFPlone.patches.z3c_form, line 46, in _wrapped
  Module z3c.form.widget, line 92, in update
  Module collective.z3cform.datagridfield.datagridfield, line 283, in value
  Module plone.app.z3cform.converters, line 359, in toWidgetValue
  Module plone.app.z3cform.converters, line 359, in <listcomp>
TypeError: ('Could not adapt', 'd', <InterfaceClass plone.uuid.interfaces.IUUID>)
class IArticlesExpander(Interface):

    box_type = schema.Choice(
        title=_("label_box_type"),
        vocabulary="my.policy.vocabularies.BoxType",
    )

    directives.widget(
        "related_links",
        RelatedItemsFieldWidget,
        vocabulary="plone.app.vocabularies.Catalog",
        pattern_options={
            "selectableTypes": ["Link"],
        },
    )
    related_links = RelationList(
        title=_(u"label_related_links", default=u"Related Links"),
        default=[],
        value_type=RelationChoice(
            title=u"Related", vocabulary="plone.app.vocabularies.Catalog"
        ),
        required=False,
    )

schema.Choice works without RelationList. The error must come from RelationList/RelatedItemsFieldWidget.

zopyx commented 2 years ago

Confirmed

zopyx commented 2 years ago

Preliminary investigation of the traceback:


  Module collective.z3cform.datagridfield.datagridfield, line 283, in value
  Module plone.app.z3cform.converters, line 361, in toWidgetValue
  Module plone.app.z3cform.converters, line 362, in <listcomp>

plone.app.z3cform.converters

value is a UUID (as string). Expected: list of UUIDs So the list comprehension iterates over the single chars of the UUID which explains the adapation error for single chars of the UUID.

As a workaround, I tried to converted value into [value]. With this workaround, the IUUID lookup fails for a correct (existing UUID). I verified that by searching for the portal_catalog by the given UUID.

So obviously, a list of UUIDs get converted somewhere in the stack to a string (or even the UI sends improper data).

zopyx commented 2 years ago

A modified version of the converter seems to work for us and possibly resolves the problem

    def toWidgetValue(self, value):
        """Converts from field value to widget.

        :param value: List of catalog brains.
        :type value: list

        :returns: List of of UID separated by separator defined on widget.
        :rtype: string
        """
        if not value:
            return self.field.missing_value
        separator = getattr(self.widget, "separator", ";")
        if IRelationList.providedBy(self.field):
            if isinstance(value, str):
                value = [value]
                return separator.join(v for v in value if v)
            else:
                return separator.join([IUUID(o) for o in value if o])
        else:
            return separator.join(v for v in value if v)
petschki commented 1 year ago

Confirmed. I've made a PR here https://github.com/collective/collective.z3cform.datagridfield/pull/142 ... turns out, that the context binding on the IChoice columns was wrong ... with this fix it works for me.

petschki commented 1 year ago

One more update here #150 I've fixed the DictRowConverter to correctly convert the columns to their schema field/widget values. This fixes several issues for me when using Choice fields in the DictRow schema.

laulaz commented 1 year ago

@petschki I can confirm that your PR fixes the issue where the relation field is not working correctly šŸ‘

laulaz commented 1 year ago

Fixed by #150 šŸ‘