How to Implement _origin in Odoo?


✅ What is _origin?

In Odoo, every recordset has a special attribute called _origin, which refers to the original database record that a given record was derived from — before any changes or duplication.

This attribute is especially useful when dealing with new/virtual/in-memory records (e.g., created using copy(), new(), or in transient models).


🔍 Use Case

_origin is often used internally by Odoo to:

  • Detect whether a record is newly created or duplicated.
  • Compare with the original record.
  • Track original references during onchange, copy, or create flows.


✅ Realistic Odoo Example


🧾 Use Case: Copying a Sale Order and Reusing Certain Fields from the Original


class SaleOrder(models.Model):

    _inherit = 'sale.order'


    def copy(self, default=None):

        res = super().copy(default)

        

        if self._origin:

            _logger.info(f"Copied from: {self._origin.name}")

            # Use something from the original

            res.note = f"Copied from order: {self._origin.name}"

        return res

🔁 What's Happening:

    • self is the temporary, new copy (not yet committed).
    • self._origin is the original sale order being copied.
    • You can access fields from _origin to carry over notes, references, or custom values.



    🧠 Where _origin is Used


    Scenario

    Purpose of _origin

    record.copy()

    Reference to the original source record

    record.new(data)

    Keeps track of the original DB record

    Transient models (wizards)

    Often used to compare input vs original

    Onchange methods

    Compare user input with source values


    ❗️ Important Notes

    • _origin is only relevant in virtual/in-memory contexts.
    • For regular, saved records: record == record._origin
    • record._origin.id gives you the original database ID.


    ✅ Summary


    Attribute

    _origin

    Used In

    Virtual/unsaved/temporary recordsets

    Points To

    Original database record

    Use Case

    Compare values, fetch original refs

    Common In

    copy(), new(), transient models