How to update mybrains object?

I want to change a mybrains object. Can someone point me to the right docs?

What I have done so far is to get the catalog, get the item, change the item. But there is no save() function! How does the change take effect? What do I need to do?

here is the code:

catalog = app.intranet.portal_catalog._catalog
all_news_items = catalog.searchResults({'portal_type': 'News Item'})
# WHAT GOES HERE? There is no save() function!

You can modify the original object but not a search result object. A brain is only a proxy with the indexed metadata and it is readonly. Call getObject() on the brain for retrieving the original object.


Ok, got the object with getObject()... how do I save my changes? I still have the same problem. How do I change an object?

You can not easily change the portal type of an object from A to B this way...this much more complicated.


Ok... are there any docs for doing that? Do you have any references I can study?
How about creating an object? If I cannot modify it then maybe I can create a new one with same parameters just different type. How would one do that? Again, any docs on this? I searched in the docs and couldn't find anything.

Check out plone.api:

The first thing to state the problem that you are trying to solve instead of throwing inconsistent sentences into the thread...what are you trying to do?

That means update it. Change the values inside said object. There is nothing inconsistent here.
I am trying to change the values inside a mybrains object. I don't know how else to explain it.

Here is more explanation:
1- I have a mybrains object that is of type "News Item"
2- I want to change the type to another type (already added as index) "newtype"
3- You said this is too hard, so I asked if I could just create a new (copy) of the News Item with the "newtype" as type. Then I asked for docs explaining how to do that.

I hope that is clear now.

Thank you

I'll add my 2 cents. Keep this in mind: you need to understand how things work in the Plone CMS and why some things make sense while others don't.

Let's suppose your new portal type is a copy of the old one and what you're trying to do is to "migrate" some objects to the new portal type. In this case, you should grab the real objects, with brain.getObject(), set the portal_type attribute, obj.portal_type = 'bla' and, depending on how you get there, you may need to commit the transaction: import transaction; transaction.commit(). Of course, test this first.

The reason you can't do this change on the brain: the brain is just a collection of information extracted from the real object. This info is updated whenever the real object changes. If you (could) update the brain, but not the real object, you'll end up with "wrong" info at first occasion when that object is edited.

1 Like

You are stilling lacking an explanation why you want to do that. But as indicated: you create a new content object using plone.api.content.create() and re-assign the properties from the old content object (not from its brain) to the newly created object.


@pe82 Changing metadata and indexes in the catalog is all documented and not to hard. Including if you want to make a generated metadata thats not actually stored as an attribute of the object.

But as @zopyx points out it looks like you might be doing something completely different because you mention changing the portal_type which is very unusual and unlikely to achieve the result u might thing. So can you give the full context of what kind of site,app,view etc you have and what is the result you are trying to end up with?

Well the point is to migrate News Items to a new portal_type that is basically a clone of News Items with different portal_type.
That's why I thought I could change the portal type.
Now I understand that I need to take the object and commit it as tiberiuichim said.
Is this correct?

You will need to use plone.api to loop through all the current News Items, and create a new news item of each as the new type. You cannot just change the type of an existing item.

Exactly. And how do I do that? Do I need to iterate over the fields too or can I just take the object and save it as another type?

You will have to copy each field over.


actually you can change the type (portal_type) of an object if it is using the same meta_type (class).

If you created your new portal_type in ZMi-->portal_types as a copy of News item, then you may just change the portal_type attribute then reindex the object.

Based on the brain :

obj = brain.getObject()
obj.portal_type = 'my_new_type'  # the id of your new portal_type

I already did that successfully. Take care that portal_type related functionnalities (workflow, search, ...) we need to be the same as original portal_type too. Look in ZMi-->portal_workflow before migrating a copy of your data.


1 Like

The usual way to this is: for every existing object of this type, create a new object and copy every field over to this new object. You want to do this, because in most cases also your base class is different for the new news items object. And you can't just change that. Every other attribute you can change as stated above. Usually that's all what you need to do. There is no save method btw. The only thing it needs to save the data or lets say make it persistent, is to commit the transaction.
Usually this is done by Plone in the background, but you can do this manually too, like @beetween mentioned.