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
Fix object creation events #549
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job pulling out the right pieces from CMFCore to make this happen. It mostly looks good, but I made one small suggestion.
id_ = obj.getId() | ||
# Archetypes objects are already created in a container thus we just fire | ||
# the notification events. | ||
if container == aq_parent(obj): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comparing acquisition-wrapped objects with ==
can be problematic (two different wrappers of the same object are not equal). Probably best to do if aq_base(container) is aq_base(aq_parent(obj))
And maybe we should raise an exception if obj already has a different parent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I've amended that.
Not sure, how a different parent would be possible at all? Have you something in mind how this could happen?
4f509a1
to
c68cc2e
Compare
@buchi this is at least a possible breaking change, correct? |
c68cc2e
to
1a2dadf
Compare
@tisto It shouldn't break anything unless you're heavily relying on plone.restapi internals, e.g. customizing the endpoint for adding objects. |
1a2dadf
to
b612cb3
Compare
@tisto Turns out this can break custom content deserializers. I've added a note to the changelog. |
@buchi thank you! Would you mind adding that section to our upgrade guide as well? |
else: | ||
rval = container._setObject(id_, obj) | ||
new_id = isinstance(rval, basestring) and rval or id_ | ||
return container._getOb(new_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_setObject triggers ObjectAddedEvent which can end up triggering a content rule to move the item to a different container. In this case we might need the same workaround that we use in plone.dexterity.utils.addContentToContainer to work around this edge case:
try:
return container._getOb(newName)
except AttributeError:
uuid = IUUID(object)
return uuidToObject(uuid)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added that.
Setting `create=True` indicates the creation of a new object and prevents firing modified events.
Change object creation and deserialization order: 1. Create an empty object 2. Deserialize it 3. Fire object created event 4. Add object to container 5. Fire object added and container modified events
Fixes vocabularies depending on tools in deserialization.
b612cb3
to
ce6e304
Compare
ce6e304
to
f112d1c
Compare
@tisto added small section in the upgrade guide. |
@buchi awesome. Thank you! |
This makes object creation in plone.restapi behave more like TTW object creation.
New objects are now created in the following way:
Before that change new objects were created in the this way: