Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues using a RelationChoice in a datagrid row #50

Open
neilferreira opened this issue Oct 25, 2016 · 0 comments
Open

Issues using a RelationChoice in a datagrid row #50

neilferreira opened this issue Oct 25, 2016 · 0 comments

Comments

@neilferreira
Copy link
Contributor

When a RelationChoice is added directly into a dexterity type the value is converted to a RelationValue prior to being saved into the database.

When a RelationChoice is added into a data grid row, the value is stored as the object that was selected but Plone has issues re-loading this object from a cold-start when Plone restarts.

I was able to resolve this by implementing this datagrid converter into my project, you may be able to think of a more elegant way to implement this directly into the datagrid

I will try to create a unit test for this soon which shows the issue in comparison between a regular content type's fields and when this field is inside of a data grid.

import zope.interface
import zope.schema.interfaces
from z3c.form.converter import BaseDataConverter
from z3c.relationfield.interfaces import IRelationChoice
from z3c.relationfield import RelationValue
from zope.intid.interfaces import IIntIds
from collective.z3cform.datagridfield.interfaces import IDataGridField
from zope import component


class GridDataConverter(BaseDataConverter):
    """ The usual behaviour for a RelationChoice schema field is for the
        value to be stored as a RelationValue in the the ZODB.
        The default behaviour by the z3cform datagrid is to store the item
        as-is.
        As a result a strange bug occurs where the value is saved as an object.
        When a cold-start occurs however, the item can not be loaded again as
        object's can directly be stored on a RelationChoice

        What we've done is converted the RelationChoice schema fields into
        RelationValue objects prior to persisting it into ZODB.
    """
    zope.component.adapts(zope.schema.interfaces.IList, IDataGridField)

    def toWidgetValue(self, value):
        for row in value:
            for key in row:
                if IRelationChoice.providedBy(self.field.value_type.schema[key]):
                    row[key] = row[key].to_object
        return value

    def toFieldValue(self, value):
        intids = component.queryUtility(IIntIds)
        for row in value:
            for key in row:
                if IRelationChoice.providedBy(self.field.value_type.schema[key]):
                    row[key] = RelationValue(intids.getId(row[key]))
        return value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant