[IMP] models: rework the API that deals with dirty fields on records
authorRaphael Collet <rco@openerp.com>
Mon, 24 Nov 2014 14:31:18 +0000 (15:31 +0100)
committerRaphael Collet <rco@openerp.com>
Mon, 24 Nov 2014 14:31:18 +0000 (15:31 +0100)
openerp/fields.py
openerp/models.py

index 69869db..d820659 100644 (file)
@@ -791,7 +791,7 @@ class Field(object):
             if env.in_onchange:
                 for invf in self.inverse_fields:
                     invf._update(value, record)
-                record._set_dirty_by(self.name)
+                record._set_dirty(self.name)
 
             # determine more dependent fields, and invalidate them
             if self.relational:
@@ -1577,9 +1577,8 @@ class _RelationalMulti(_Relational):
 
         # add new and existing records
         for record in value:
-            if not record.id or record._dirty:
-                dirty_fields = record.env.dirty[record]
-                values = dict((k, v) for k, v in record._cache.iteritems() if k in fnames and k in dirty_fields)
+            if not record.id or record._is_dirty():
+                values = {k: record._cache[k] for k in record._get_dirty() if k in fnames}
                 values = record._convert_to_write(values)
                 if not record.id:
                     result.append((0, 0, values))
index d44ced4..36c29e3 100644 (file)
@@ -5313,16 +5313,21 @@ class BaseModel(object):
         return record
 
     #
-    # Dirty flag, to mark records modified (in draft mode)
+    # Dirty flags, to mark record fields modified (in draft mode)
     #
 
-    @property
-    def _dirty(self):
+    def _is_dirty(self):
         """ Return whether any record in `self` is dirty. """
         dirty = self.env.dirty
-        return any(bool(dirty.get(record)) for record in self)
+        return any(record in dirty for record in self)
+
+    def _get_dirty(self):
+        """ Return the list of field names for which `self` is dirty. """
+        dirty = self.env.dirty
+        return list(dirty.get(self, ()))
 
-    def _set_dirty_by(self, field_name):
+    def _set_dirty(self, field_name):
+        """ Mark the records in `self` as dirty for the given `field_name`. """
         dirty = self.env.dirty
         for record in self:
             dirty[record].add(field_name)
@@ -5727,7 +5732,7 @@ class BaseModel(object):
                     field = self._fields[name]
                     newval = record[name]
                     if field.type in ('one2many', 'many2many'):
-                        if newval != oldval or newval._dirty:
+                        if newval != oldval or newval._is_dirty():
                             # put new value in result
                             result['value'][name] = field.convert_to_write(
                                 newval, record._origin, subfields.get(name),