Do not use init values for new record without id to compute the changed values
When using new instance to fill a xxx2Many field, all the values must be considered as changed and we should not expect any initial value. Closes #13716
This commit is contained in:
1 parent
34df4552e5
commit
1360ae6c5d
3 files changed
+42
-19
No files matched your search
@@ -284,6 +284,8 @@ class Model(URLMixin, PoolBase, metaclass=ModelMeta):
|
||||
id = int(id)
|
||||
self._id = id
|
||||
self._deleted = self._removed = None
|
||||
self._values = None
|
||||
self._init_values = None
|
||||
if kwargs:
|
||||
self._values = self._record()
|
||||
parent_values = defaultdict(dict)
|
||||
@@ -305,10 +307,8 @@ class Model(URLMixin, PoolBase, metaclass=ModelMeta):
|
||||
# to ensure it was evaluated with all the fields
|
||||
for name, value in has_context.items():
|
||||
setattr(self, name, value)
|
||||
self._init_values = self._values._copy()
|
||||
else:
|
||||
self._values = None
|
||||
self._init_values = None
|
||||
if id is not None:
|
||||
self._init_values = self._values._copy()
|
||||
|
||||
def __copy__(self):
|
||||
copied = self.__class__(self.id)
|
||||
|
||||
@@ -870,7 +870,9 @@ class ModelView(Model):
|
||||
value = value.id
|
||||
elif field._type in ['one2many', 'many2many']:
|
||||
targets = value
|
||||
if fname in init_values:
|
||||
if self.id is None:
|
||||
init_targets = []
|
||||
elif fname in init_values:
|
||||
init_targets = init_values._get(fname)
|
||||
elif isinstance(field, fields.Function):
|
||||
init_targets = []
|
||||
@@ -898,14 +900,7 @@ class ModelView(Model):
|
||||
value['update'].append(target_changed)
|
||||
else:
|
||||
if isinstance(target, ModelView):
|
||||
# Ensure initial values are returned because
|
||||
# target was instantiated on server side.
|
||||
target_init_values = target._init_values
|
||||
target._init_values = None
|
||||
try:
|
||||
added_values = target._changed_values()
|
||||
finally:
|
||||
target._init_values = target_init_values
|
||||
added_values = target._changed_values()
|
||||
else:
|
||||
added_values = target._default_values
|
||||
added_values['id'] = target.id
|
||||
|
||||
@@ -185,7 +185,7 @@ class ModelView(TestCase):
|
||||
Model = pool.get('test.modelview.changed_values')
|
||||
Target = pool.get('test.modelview.changed_values.target')
|
||||
|
||||
record = Model(targets=[], m2m_targets=[], m2m_function=[])
|
||||
record = Model(id=-1, targets=[], m2m_targets=[], m2m_function=[])
|
||||
|
||||
self.assertEqual(record._changed_values(), {})
|
||||
|
||||
@@ -208,7 +208,7 @@ class ModelView(TestCase):
|
||||
'dictionary': {'key': 'value'},
|
||||
})
|
||||
|
||||
record = Model(name='test', target=1, targets=[
|
||||
record = Model(id=-1, name='test', target=1, targets=[
|
||||
{'id': 1, 'name': 'foo'},
|
||||
{'id': 2},
|
||||
],
|
||||
@@ -243,7 +243,7 @@ class ModelView(TestCase):
|
||||
})
|
||||
|
||||
# change only one2many record
|
||||
record = Model(targets=[{'id': 1, 'name': 'foo'}])
|
||||
record = Model(id=-1, targets=[{'id': 1, 'name': 'foo'}])
|
||||
self.assertEqual(record._changed_values(), {})
|
||||
|
||||
target, = record.targets
|
||||
@@ -256,7 +256,7 @@ class ModelView(TestCase):
|
||||
})
|
||||
|
||||
# no initial value
|
||||
record = Model(targets=[], m2m_targets=[], m2m_function=[])
|
||||
record = Model(id=-1, targets=[], m2m_targets=[], m2m_function=[])
|
||||
record._values = record._record()
|
||||
target = Target(id=1)
|
||||
record._values['targets'] = [target]
|
||||
@@ -267,6 +267,34 @@ class ModelView(TestCase):
|
||||
},
|
||||
})
|
||||
|
||||
@with_transaction()
|
||||
def test_changed_values_with_no_id(self):
|
||||
"Test changed values with no id"
|
||||
pool = Pool()
|
||||
Model = pool.get('test.modelview.changed_values')
|
||||
Target = pool.get('test.modelview.changed_values.target')
|
||||
|
||||
record = Model(
|
||||
name='foo',
|
||||
target=Target(1),
|
||||
ref_target=Target(2),
|
||||
targets=[Target(name='bar')],
|
||||
multiselection=['a'],
|
||||
dictionary={'key': 'value'})
|
||||
|
||||
self.assertEqual(record._changed_values(), {
|
||||
'name': 'foo',
|
||||
'target': 1,
|
||||
'ref_target': 'test.modelview.changed_values.target,2',
|
||||
'targets': {
|
||||
'add': [
|
||||
(0, {'id': None, 'name': 'bar'}),
|
||||
],
|
||||
},
|
||||
'multiselection': ('a',),
|
||||
'dictionary': {'key': 'value'},
|
||||
})
|
||||
|
||||
@with_transaction()
|
||||
def test_changed_values_2many_function(self):
|
||||
"Test changed values for xxx2many function field"
|
||||
@@ -315,7 +343,7 @@ class ModelView(TestCase):
|
||||
Target = pool.get('test.modelview.changed_values.target')
|
||||
|
||||
target = Target(1)
|
||||
record = Model(targets=[target])
|
||||
record = Model(id=-1, targets=[target])
|
||||
Model.targets.remove(record, [target])
|
||||
|
||||
self.assertEqual(record._changed_values(), {
|
||||
@@ -332,7 +360,7 @@ class ModelView(TestCase):
|
||||
Target = pool.get('test.modelview.changed_values.target')
|
||||
|
||||
target = Target(1)
|
||||
record = Model(m2m_targets=[target])
|
||||
record = Model(id=-1, m2m_targets=[target])
|
||||
Model.m2m_targets.delete(record, [target])
|
||||
|
||||
self.assertEqual(record._changed_values(), {
|
||||
|
||||
Reference in new issue
Block a user