summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odoo/fields.py16
-rw-r--r--odoo/models.py47
-rw-r--r--odoo/modules/registry.py20
3 files changed, 45 insertions, 38 deletions
diff --git a/odoo/fields.py b/odoo/fields.py
index ad0c167588f..2f4764f6233 100644
--- a/odoo/fields.py
+++ b/odoo/fields.py
@@ -594,18 +594,22 @@ class Field(MetaField('DummyField', (object,), {})):
# Setup of field triggers
#
- def resolve_depends(self, model):
+ def resolve_depends(self, registry):
""" Return the dependencies of `self` as a collection of field tuples. """
+ Model0 = registry[self.model_name]
+
for dotnames in self.depends:
field_seq = []
- field_model = model
+ model_name = self.model_name
+
for index, fname in enumerate(dotnames.split('.')):
- if model._transient and not field_model._transient:
+ Model = registry[model_name]
+ if Model0._transient and not Model._transient:
# modifying fields on regular models should not trigger
# recomputations of fields on transient models
break
- field = field_model._fields[fname]
+ field = Model._fields[fname]
if field is self and index:
self.recursive = True
@@ -618,10 +622,10 @@ class Field(MetaField('DummyField', (object,), {})):
yield tuple(field_seq)
if field.type in ('one2many', 'many2many'):
- for inv_field in field_model._field_inverses[field]:
+ for inv_field in Model._field_inverses[field]:
yield tuple(field_seq) + (inv_field,)
- field_model = model.env.get(field.comodel_name)
+ model_name = field.comodel_name
############################################################################
#
diff --git a/odoo/models.py b/odoo/models.py
index 1ccdfd55ec0..9b8bd13d507 100644
--- a/odoo/models.py
+++ b/odoo/models.py
@@ -2780,27 +2780,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
""" Setup recomputation triggers, and complete the model setup. """
cls = type(self)
- # The triggers of a field F is a tree that contains the fields that
- # depend on F, together with the fields to inverse to find out which
- # records to recompute.
- #
- # For instance, assume that G depends on F, H depends on X.F, I depends
- # on W.X.F, and J depends on Y.F. The triggers of F will be the tree:
- #
- # [G]
- # X/ \Y
- # [H] [J]
- # W/
- # [I]
- #
- # This tree provides perfect support for the trigger mechanism:
- # when F is # modified on records,
- # - mark G to recompute on records,
- # - mark H to recompute on inverse(X, records),
- # - mark I to recompute on inverse(W, inverse(X, records)),
- # - mark J to recompute on inverse(Y, records).
- cls._field_triggers = cls.pool.field_triggers
-
# register constraints and onchange methods
cls._init_constraints_onchanges()
@@ -5732,13 +5711,33 @@ Record ids: %(records)s
"""
if not self or not fnames:
return
+
+ # The triggers of a field F is a tree that contains the fields that
+ # depend on F, together with the fields to inverse to find out which
+ # records to recompute.
+ #
+ # For instance, assume that G depends on F, H depends on X.F, I depends
+ # on W.X.F, and J depends on Y.F. The triggers of F will be the tree:
+ #
+ # [G]
+ # X/ \Y
+ # [H] [J]
+ # W/
+ # [I]
+ #
+ # This tree provides perfect support for the trigger mechanism:
+ # when F is # modified on records,
+ # - mark G to recompute on records,
+ # - mark H to recompute on inverse(X, records),
+ # - mark I to recompute on inverse(W, inverse(X, records)),
+ # - mark J to recompute on inverse(Y, records).
if len(fnames) == 1:
- tree = self._field_triggers.get(self._fields[next(iter(fnames))])
+ tree = self.pool.field_triggers.get(self._fields[next(iter(fnames))])
else:
# merge dependency trees to evaluate all triggers at once
tree = {}
for fname in fnames:
- node = self._field_triggers.get(self._fields[fname])
+ node = self.pool.field_triggers.get(self._fields[fname])
if node:
trigger_tree_merge(tree, node)
if tree:
@@ -5865,7 +5864,7 @@ Record ids: %(records)s
yield from val
else:
yield from traverse(val)
- return traverse(self._field_triggers.get(field, {}))
+ return traverse(self.pool.field_triggers.get(field, {}))
def _has_onchange(self, field, other_fields):
""" Return whether ``field`` should trigger an onchange event in the
diff --git a/odoo/modules/registry.py b/odoo/modules/registry.py
index c4bc64adfe2..ec07606d6f9 100644
--- a/odoo/modules/registry.py
+++ b/odoo/modules/registry.py
@@ -261,16 +261,23 @@ class Registry(Mapping):
for model in models:
model._setup_fields()
+ for model in models:
+ model._setup_complete()
+
+ self.registry_invalidated = True
+
+ @lazy_property
+ def field_triggers(self):
# determine field dependencies
dependencies = {}
- for model in models:
- if model._abstract:
+ for Model in self.models.values():
+ if Model._abstract:
continue
- for field in model._fields.values():
+ for field in Model._fields.values():
# dependencies of custom fields may not exist; ignore that case
exceptions = (Exception,) if field.base_field.manual else ()
with ignore(*exceptions):
- dependencies[field] = set(field.resolve_depends(model))
+ dependencies[field] = set(field.resolve_depends(self))
# determine transitive dependencies
def transitive_dependencies(field, seen=[]):
@@ -299,10 +306,7 @@ class Registry(Mapping):
tree = tree.setdefault(label, {})
tree.setdefault(None, set()).add(field)
- self.field_triggers = triggers
-
- for model in models:
- model._setup_complete()
+ return triggers
def post_init(self, func, *args, **kwargs):
""" Register a function to call at the end of :meth:`~.init_models`. """