This question has been flagged
3 Replies
46099 Views

I'm trying to update a many2many field from website via a <select multiple> element.

However, I'm unable to store already existing ids along with newly selected options.


For example, the many2many relation holds the ids 1,2,3. Now, upon updating the new ids would supposed to be 1,2,3,4,5 based on the selected <option>s in the <select> - but only the new ids (4,5) are stored, 1,2,3 get removed.


values['field'] = (6, 0, [1,2,3,4,5])
res.write(values)


Any hints, why this could be happening? Maybe I'm misinterpreting the documentation saying "(6, _, ids)

replaces all existing records in the set by the ids list, equivalent to using the command 5 followed by a command 4 for each id in ids." (https://www.odoo.com/documentation/12.0/reference/orm.html#model-reference)?


---

Edit fyi:

Model:

_inherit = 'res.partner'
field = fields.Many2many(comodel_name='res.country', relation="some_country_res_partner_rel", string='Some countries', default=False)



Avatar
Discard

values['field'] = [(6, 0, [1,2,3,4,5])]

Author

Nope, "values" (at the time of "res.write(values)") is {'field': (6, 0, ['1', '2','3','4','5'])} - your suggestion would get me {'field': ([(6, 0, ['1', '2','3','4','5'])],)} which then does not update the many2many field at all (already set relations are kept in that case though)

Best Answer


Update 2022, Odoo 15.0 and later. You can use the new Command-helper API.

  • (0, 0, { values }) -- Command.create({...})
  • (1, ID, { values }) -- Command.update({...})
  • (2, ID) -- Command.delete(...)
  • (3, ID) -- Command.unlink(...)
  • (4, ID) -- Command.link(...)
  • (5) -- Command.clear()
  • (6, 0, [IDs]) -- Command.set([...])

The Command-helpers will create the typles with the right number from record ids or values, e.g.

my_obj.write({'ur_m2m_field': [Command.link(id)]})


Avatar
Discard
Best Answer

You should use (4, id) in the write method.

Ex:

for id in [4,5]:
my_obj.write({'ur_m2m_field': [(4, id)]})

There are actually0-6 numbers for representing each job for a many2many/ one2many field

  • (0, 0, { values }) -- link to a new record that needs to be created with the given values dictionary
  • (1, ID, { values }) -- update the linked record with id = ID (write values on it)
  • (2, ID) -- remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as well)
  • (3, ID) -- cut the link to the linked record with id = ID (delete the relationship between the two objects but does not delete the target object itself)
  • (4, ID) -- link to existing record with id = ID (adds a relationship)
  • (5) -- unlink all (like using (3,ID) for all linked records)
  • (6, 0, [IDs]) -- replace the list of linked IDs (like using (5) then (4,ID) for each ID in the list of IDs)
Avatar
Discard
Author

Yes, in fact this would store ADDITIONAL relations, but what if one deselects something from <select multiple> (assume the m2m field holds currently ids 1,2 - now one wants to set 1,3,4; in your example i would end up with 1,2,3,4). Judging by the documentation one would probably do (5,_,_) and then (4,id) - which in return should be equal to (6,_,ids) [at least based on the documentation..?] - or can you think about another way of making sure that all actually selected options get stored -- or am I completely mistaken now?

Author

had some further tries:

<select multiple> --> changing from no selection to Afghanistan

{'field': [(5, 0, 0), (4, '3')]} --> will be stored

Saving the same form again (Afghanistan still selected)

{'field': [(5, 0, 0), (4, '3')]} --> will not be stored anylonger - so it behaves pretty much like my initial try with (6,0,ids) for some reason...

Best Answer

Hi, I am using Odoo 14 and Sudhir answer works, but it seems that Odoo is protecting itself because it gets back in a second to the original values. I am trying to link an invoice to as sale order, so I am using:

record.write({'invoice_ids': [(3, 456)]}) #456 is the record of the invoice
raise Warning(record.invoice_ids)

The warning shows that the new Id has been appended to the current values, but if I check again in the next second, the values get back to the original. Any clue on how to make them persistent?

Thx.


Avatar
Discard