[FIX] models: in onchange(), do not send a field value if it has not changed
authorRaphael Collet <rco@openerp.com>
Wed, 10 Sep 2014 12:55:28 +0000 (14:55 +0200)
committerRaphael Collet <rco@openerp.com>
Thu, 11 Sep 2014 09:45:23 +0000 (11:45 +0200)
The method onchange() executes onchange methods in cascade.  Suppose onchange()
is called and a field F=1 in the form.  If an onchange method set F=2, that
value is put in the result variable.  If another onchange method set it back to
F=1, the binding F=2 must be removed from the result variable.

Fixes #2309

openerp/models.py

index b531678..a309450 100644 (file)
@@ -5693,14 +5693,28 @@ class BaseModel(object):
 
                 # determine which fields have been modified
                 for name, oldval in values.iteritems():
-                    newval = record[name]
                     field = self._fields[name]
-                    if newval != oldval or \
-                            field.type in ('one2many', 'many2many') and newval._dirty:
-                        result['value'][name] = field.convert_to_write(
-                            newval, record._origin, subfields.get(name),
-                        )
-                        todo.add(name)
+                    newval = record[name]
+                    if field.type in ('one2many', 'many2many'):
+                        if newval != oldval or newval._dirty:
+                            # put new value in result
+                            result['value'][name] = field.convert_to_write(
+                                newval, record._origin, subfields.get(name),
+                            )
+                            todo.add(name)
+                        else:
+                            # keep result: newval may have been dirty before
+                            pass
+                    else:
+                        if newval != oldval:
+                            # put new value in result
+                            result['value'][name] = field.convert_to_write(
+                                newval, record._origin, subfields.get(name),
+                            )
+                            todo.add(name)
+                        else:
+                            # clean up result to not return another value
+                            result['value'].pop(name, None)
 
         # At the moment, the client does not support updates on a *2many field
         # while this one is modified by the user.