Patrick Downey
Patrick Downey

Reputation: 965

Plone/IRelatedItems- How can I programatically set relatedItems of a dexterity content type?

In an event, IAfterTransitionEvent, I'm trying to capture the event of an object being published and when the object is published, two objects are created and I want to relate.

In the type xml file of the object that's being published, I added to behaviors:

element value="plone.app.relationfield.behavior.IRelatedItems"

So that I could get relatedItems.

In my event function, I have:

@grok.subscribe(InitialContract, IAfterTransitionEvent)
def itemPublished(obj, event):
    site = api.portal.get()
    if event.status['action'] == 'publish':

        house_agreement = customCreateFunction(container...,type..)
        #I get the HouseAgreement object
        labor_contract = customCreateFunction(container....,type)
        #I get the LaborContract object
        relIDs = []
        relIDs.append(RelationValue(IUUID(house_agreement)))
        relIDs.append(RelationValue(IUUID(labor_contract)))

        obj.relatedItems = relIDs

Unfortunately, printing obj.relatedItems gives me an empty list and when I go to the View class and look under Categorization, the Related Items field is empty. I tried _relatedItems instead of relatedItems, but that doesn't seem to work as I think its creating an attribute for the obj. I also tried just using IUUID instead of also converting it to a RelationValue, but that doesn't give me any error at all.

It is like it is not setting the relatedItems value, yet seems to accept the list being passed.

If its possible, how can I programmatically set relatedItems?

Also, I do plan on adding code to prevent objects from being added twice.

Upvotes: 4

Views: 570

Answers (1)

Mathias
Mathias

Reputation: 6839

You need to store a list of RelationValues.

>>> from zope.component import getUtility
>>> from zope.intid.interfaces import IIntIds
>>> from z3c.relationfield import RelationValue


>>> intids = getUtility(IIntIds)
>>> source.relatedItems = [RelationValue(self.intids.getId(target))]
>>> source.relatedItems
[<z3c.relationfield.relation.RelationValue object at 0x10bf2eed8>]

You can now access the target by...

>>> target_ref = source.relatedItems[0]
>>> target_ref.to_object
<XXX at / Plone/target>

The important change on my code example is:

  • RelationValues are based on Intid not uuid.

Upvotes: 5

Related Questions