OdooWiki OCA HUB

Base - Write Diff

base_write_diff folder_open OCA/server-tools open_in_new
Hidden License: AGPL-3

This module allows filtering values to update on records according to whether they are actually different from the records' current values.

auto_awesome What this module does

AI-generated from the code · Odoo 19.0

Prevents Odoo from saving field values that are identical to what is already stored, so records are only updated when something really changes. It adds a new write_diff method that developers can use to skip useless updates.

This module changes how Odoo saves changes on records. Normally, when a value is written to a record, Odoo stores it even if the new value is exactly the same as the current one. With this module, a new method called write_diff is available on all records: it compares the values you want to save with the values already in the record and only keeps the fields that are genuinely different.

  • If nothing is different, no update is performed at all.
  • For related lists (one2many and many2many fields), it also checks the lines inside and removes unchanged sub-values.
  • The normal write behaviour is only affected when the special context flag write_use_diff_values is set, so existing code keeps working as before.

There is no new menu or screen: this is a hidden technical module used by other modules and developers. It touches the base model (base) that every Odoo record inherits from, and it relies on the record snapshot feature from the web module. Business users will notice fewer unnecessary change entries in the chatter and fewer triggered automations when a save does not actually modify anything.

Depends on

baseweb
Models and fields (1)
  • base · extends an existing model

Text generated by AI (DeepSeek) from reading the Odoo 19.0 code on GitHub; it may contain mistakes, so check the code before deciding. View the code on GitHub

Availability by version

Reviewed: 2026-11-03
Confirmed (verified in repository and branch) Estimated (unverified) No information

Confirmation status: 2 confirmed, 7 with no information of 9 versions.

Sources · Odoo 17.0

Confirmed on 2026-11-03 in branch 17.0 of OCA/server-tools.

terminal Installation and usage

OCA documentation · Odoo 19.0

Summary

This module allows you to update records by filtering out fields whose values are going to be left unchanged by BaseModel.write(); for example, let's assume you have:

>>> self
sale.order.line(1,)
>>> self.price_unit
10.00

If you use self.write({"price_unit": 10.00}) or self.price_unit = 10.00, Odoo may end up executing unnecessary operations, like triggering the update on the field, recompute computed fields that depend on price_unit, and so on, even if the value is actually unchanged.

By using this module, you can prevent all of that.

You can use this module in 3 different ways. All of them require you to add this module as a dependency of your module.

1 - Context key "write_use_diff_values"

By adding write_use_diff_values=True to the context when updating a field value, the BaseModel.write() patch will take care of filtering out the fields' values that are the same as the record's current ones.

⚠️ Beware: the context key is propagated down to other write() calls

Example:

from odoo import models


class ProductTemplate(models.Model):
    _inherit = "product.template"

    def write(self, vals):
        # Update only fields that are actually different
        self = self.with_context(write_use_diff_values=True)
        return super().write(vals)


class ProductProduct(models.Model):
    _inherit = "product.product"

    def update_code_if_necessary(self, code: str):
        # Update ``default_code`` only if different from the current value
        self.with_context(write_use_diff_values=True).default_code = code

2 - Method BaseModel.write_diff()

It is the same as calling write(), but it automatically enables the "write_use_diff_values" context flag: self.write_diff(vals) is a shortcut for self.with_context(write_use_diff_values=True).write(vals)

⚠️ Beware: the context key is propagated down to other write() calls

3 - Method BaseModel._get_write_diff_values(vals)

This method accepts a write-like dict as param, and returns a new dict made of the fields who will actually update the record's values. This allows for a more flexible and customizable behavior than the context key usage, because:

  • you'll be able to filter out specific fields, instead of filtering out all the fields whose values won't be changed after the update;
  • you'll be able to execute the filtering on specific models, instead of executing it on all the models involved in the stack of write() calls from the first usage of the context key down to the base method BaseModel.write().

Example:

from collections import defaultdict

from odoo import api, models
from odoo.tools.misc import frozendict


class ProductProduct(models.Model):
    _inherit = "product.product"

    def write(self, vals):
        # OVERRIDE: ``odoo.addons.product.models.product_product.Product.write()``
        # override will clear the whole registry cache if either 'active' or
        # 'product_template_attribute_value_ids' are found in the ``vals`` dictionary:
        # remove them unless it's necessary to update them
        fnames = {"active", "product_template_attribute_value_ids"}
        if vals_to_check := {f: vals.pop(f) for f in fnames.intersection(vals)}:
            groups = defaultdict(lambda: self.browse())
            for prod in self:
                groups[frozendict(prod._get_write_diff_values(vals_to_check))] += prod
            for diff_vals, prods in groups.items():
                if res_vals := (vals | dict(diff_vals)):
                    super(ProductProduct, prods).write(res_vals)
            return True
        return super().write(vals)

No verified information in OCA: Installation, Configuration.

info

Data imported from GitHub: this sheet reflects the latest catalog review, not a live lookup. Always check the module documentation and staging before installing in production.