Search code examples
pythonodooodoo-11odoo-12

How to get the value of a dynamic many2many field in create() function


I want to get the value from of a dynamically populated many2many field in create() function, but i get this outcome [[6, False, [98]]], 98 is actually the expected outcome though this is my code below

class CustomTransRequest(models.Model):
    _name = 'custom.trans.request'
    _description = 'Transfer Request'

    branch_from_id = fields.Many2one('custom.branch', string="From", required=True)
    branch_to_id = fields.Many2one('custom.branch', string="To", required=True)
    line_id = fields.Many2one('custom.branch.line', string="Products", required=True)
    product_id = fields.Many2many('custom.product', required=False, )
    qty = fields.Integer(string="Qty", required=True)

    @api.onchange('line_id')
    def onchange_line(self):
        if self.line_id:
            for rec in self:
                selected_products = rec.env['custom.branch.line'].search(
                    [('id', '=', rec.line_id.id)]).mapped('product_id')
                self.product_id = [(6, 0, selected_products.ids)]

    @api.model
    def create(self, vals):
        print("Create Function ")
        print("SELECT id FROM custom_branch_line WHERE (branch_id = %s) AND (product_id = %s)" % (
            vals.get('branch_to_id'), vals['product_id']))
        result = super(CustomTransRequest, self).create(vals)
        return result

Solution

  • This how Odoo Handles X2many fields, by convention they are called command (or list of command) most of the time in the create method, the command that will be passed for your m2m fields will be:

     # only one command 6 which tell Odoo replace all record with the selected ids
     [(6, 0, [list_of_selected_record_ids)]
    

    So in order to retrieve them just do: vals['product_id'][0][2]

    No I don't know if you are just trying to show select query or you want to use, if you are just printing it:

      # replace vals['product_id'] with 
      '({})'.format(','.join(vals['product_id'][0][2]))
    

    If you will execute it, use query params:

    self.cr.execute("SELECT id FROM custom_branch_line WHERE (branch_id = %s) AND (product_id = %s)", (vals['branch_to_id'], vals['product_id'][0][2]))
    

    for more information about X2many command check this:

    One2many and Many2many use a special "commands"

    Note: I assumed that this field will not be empty if not you need to check if the fields are not empty first.