changeset b307bd41f89d in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset;node=b307bd41f89d
description:
        Fallback to stored values to compute changed xxx2Many

        The client may not send the values for the xxx2Many if they have not 
been
        loaded. So in order to provide proper changes to apply once the values 
are
        loaded we must base those changes on the current data stored.

        issue9719
        review308391002
diffstat:

 trytond/model/modelview.py      |   7 +++++--
 trytond/tests/modelview.py      |  16 ++++++++++++++++
 trytond/tests/test_modelview.py |  26 +++++++++++++++++++++++++-
 3 files changed, 46 insertions(+), 3 deletions(-)

diffs (93 lines):

diff -r ad25105834ed -r b307bd41f89d trytond/model/modelview.py
--- a/trytond/model/modelview.py        Wed Oct 21 23:23:41 2020 +0200
+++ b/trytond/model/modelview.py        Wed Oct 21 23:27:13 2020 +0200
@@ -804,6 +804,7 @@
         init_values = self._init_values or self._record()
         if not self._values:
             return changed
+        init_record = self.__class__(self.id)
         for fname, value in self._values._items():
             field = self._fields[fname]
             # Always test key presence in case value is None
@@ -826,8 +827,10 @@
                         value = value.id
             elif field._type in ['one2many', 'many2many']:
                 targets = value
-                init_targets = list(init_values._get(
-                        fname, targets if field._type == 'one2many' else []))
+                if fname in init_values:
+                    init_targets = init_values._get(fname)
+                else:
+                    init_targets = getattr(init_record, fname, [])
                 value = collections.defaultdict(list)
                 previous = [t.id for t in init_targets if t.id]
                 for i, target in enumerate(targets):
diff -r ad25105834ed -r b307bd41f89d trytond/tests/modelview.py
--- a/trytond/tests/modelview.py        Wed Oct 21 23:23:41 2020 +0200
+++ b/trytond/tests/modelview.py        Wed Oct 21 23:27:13 2020 +0200
@@ -35,6 +35,20 @@
     name = fields.Char("Name")
 
 
+class ModelViewStoredChangedValues(ModelSQL, ModelView):
+    "ModelView Stored Changed Values Stored"
+    __name__ = 'test.modelview.stored.changed_values'
+    targets = fields.One2Many(
+        'test.modelview.stored.changed_values.target', 'parent', "Targets")
+
+
+class ModelViewStoredChangedValuesTarget(ModelSQL, ModelView):
+    "ModelSQL Stored Changed Values Target"
+    __name__ = 'test.modelview.stored.changed_values.target'
+    name = fields.Char("Name")
+    parent = fields.Many2One('test.modelview.stored.changed_values', "Parent")
+
+
 class ModelViewButton(ModelView):
     'ModelView Button'
     __name__ = 'test.modelview.button'
@@ -209,6 +223,8 @@
         ModelViewChangedValues,
         ModelViewChangedValuesTarget,
         ModelViewChangedValuesStoredTarget,
+        ModelViewStoredChangedValues,
+        ModelViewStoredChangedValuesTarget,
         ModelViewButton,
         ModelViewButtonDepends,
         ModelViewButtonAction,
diff -r ad25105834ed -r b307bd41f89d trytond/tests/test_modelview.py
--- a/trytond/tests/test_modelview.py   Wed Oct 21 23:23:41 2020 +0200
+++ b/trytond/tests/test_modelview.py   Wed Oct 21 23:27:13 2020 +0200
@@ -88,7 +88,31 @@
         target.name = 'foo'
         self.assertEqual(record._changed_values, {
                 'targets': {
-                    'update': [{'id': 1, 'name': 'foo'}],
+                    'add': [(0, {'id': 1, 'name': 'foo'})],
+                    },
+                })
+
+    @with_transaction()
+    def test_changed_values_stored(self):
+        "Test stored changed values"
+        pool = Pool()
+        Model = pool.get('test.modelview.stored.changed_values')
+        Target = pool.get('test.modelview.stored.changed_values.target')
+
+        record = Model()
+        record.targets = [Target(name="foo"), Target(name="bar")]
+        record.save()
+        target1, target2 = record.targets
+
+        record = Model(record.id)
+        target1.name = "test"
+        record.targets = [target1, Target(name="baz")]
+
+        self.assertEqual(record._changed_values, {
+                'targets': {
+                    'delete': [target2.id],
+                    'update': [{'id': target1.id, 'name': "test"}],
+                    'add': [(1, {'id': None, 'name': "baz"})],
                     },
                 })
 

Reply via email to