AKHIL MATHEW AKHIL MATHEW - 8 months ago 564
Python Question

How to fetch values from a one2many field in odoo

In customer invoice in the account module there is a one2many field,

invoice_line = fields.One2many('account.invoice.line', 'invoice_id', string='Invoice Lines')

Using this field we can add multiple products in the invoice. After adding multiple products how to segregate those products from this field, so that i will get product ids.

Suppose if we save two products, we will have two entries. From these two entry i need to separate each product's product id


For your question i can only give you a general answer. I hope, you can start with it.

In a odoo model (osv.osv, ...) you can use self.pool.get("model name") to get the object pool for any model. With this pool you can use the method read() to read the data.
A Odoo model is stored mostly in one table on the database.

Firstly you need to understand the relationship of the objects in Odoo. In your case it's so:

account.invoice --(invoice_line_ids:one2many)--> account.invoice.line --(product:many2one)-> product
  • Reading of one2many field returns a list of IDs of the destination objects.
  • Reading of Many2one field returns an int value of ID of the destination object.

Here is an example to get product ids from the lines of a invoice:

# call object pool for account.invoice
invoice_pool = self.pool.get("account.invoice")

# here you need the invoice_id to get the data. 
# you can get it by parsing the parameter context
found_invoices = invoice_pool.read(cr, uid, [invoice_id,], ["invoice_line_ids"], context)

# It returns a list, but i gave only one invoice_id.
# the list has maximun one element. we need the frist element
found_invoice = found_invoices[0] if found_invoices else None

invoice_line_ids = found_invoice["invoice_line_ids"]

# the same with "account.invoice.line"
invoice_line_pool = self.pool.get("account.invoice.line")
invoice_lines = invoice_line_pool.read(cr, uid, invoice_line_ids, ["product_id"], context)

# Here you have the product ids
# I don't need to get the first element, because it returns a int
product_ids = [line["product_id"] for line in invoice_lines]

cr, uid, context are parameters, which you get from a request. You can get it by overwriting the method read, write, .... Important: you need the invoice_id to start. You can get this value by parsing the variable context.

You can use logging to show the content of context in log file:

import logging

_logger = logging.getLogger(__name__)
_logger.info("context type: " + type(context))
_logger.info("context content: " + str(context))

P/S: You will need to customize my code to fit with yours, because i don't know many about your idea. I'm working with Odoo 9. But it's mostly the same core with Odoo 8