diff --git a/trytond/model/model.py b/trytond/model/model.py index 1e4c67b3f4..cb6ff9046c 100644 --- a/trytond/model/model.py +++ b/trytond/model/model.py @@ -359,14 +359,21 @@ class Model(WarningErrorMixin, URLMixin, PoolBase): setattr(self, name, value) else: parent_values[name] = value - for name, value in parent_values.iteritems(): + + def set_parent_value(record, name, value): parent_name, field = name.split('.', 1) parent_name = parent_name[8:] # Strip '_parent_' - parent = getattr(self, parent_name, None) + parent = getattr(record, parent_name, None) if parent is not None: - setattr(parent, field, value) + if not field.startswith('_parent_'): + setattr(parent, field, value) + else: + set_parent_value(parent, field, value) else: - setattr(self, parent_name, {field: value}) + setattr(record, parent_name, {field: value}) + + for name, value in parent_values.iteritems(): + set_parent_value(self, name, value) self._init_values = self._values.copy() else: self._values = None diff --git a/trytond/tests/__init__.py b/trytond/tests/__init__.py index 50c69ae7aa..ca7cfc52be 100644 --- a/trytond/tests/__init__.py +++ b/trytond/tests/__init__.py @@ -113,6 +113,9 @@ def register(): BinaryRequired, BinaryFileStorage, Model, + ModelParent, + ModelChild, + ModelChildChild, Singleton, URLObject, ModelStorage, diff --git a/trytond/tests/model.py b/trytond/tests/model.py index 3eab4ddb4b..8ce2038446 100644 --- a/trytond/tests/model.py +++ b/trytond/tests/model.py @@ -6,6 +6,7 @@ from trytond.transaction import Transaction __all__ = [ 'Model', + 'ModelParent', 'ModelChild', 'ModelChildChild', 'Singleton', 'URLObject', 'ModelStorage', 'ModelStorageRequired', 'ModelStorageContext', 'ModelSQLRequiredField', 'ModelSQLTimestamp', 'ModelSQLFieldSet', @@ -23,6 +24,26 @@ class Model(ModelSQL): name = fields.Char('Name') +class ModelParent(Model): + "Model Parent" + __name__ = 'test.model_parent' + name = fields.Char("Name") + + +class ModelChild(Model): + "Model Child" + __name__ = 'test.model_child' + name = fields.Char("Name") + parent = fields.Many2One('test.model_parent', "Parent") + + +class ModelChildChild(Model): + "Model Child Child" + __name__ = 'test.model_child_child' + name = fields.Char("Name") + parent = fields.Many2One('test.model_child', "Parent") + + class Singleton(ModelSingleton, ModelSQL): 'Singleton' __name__ = 'test.singleton' diff --git a/trytond/tests/test_model.py b/trytond/tests/test_model.py index e5cabd4ef1..cb1469863b 100644 --- a/trytond/tests/test_model.py +++ b/trytond/tests/test_model.py @@ -28,6 +28,34 @@ class ModelTestCase(unittest.TestCase): self.assertEqual( repr(record), "Pool().get('test.model')(%s)" % record.id) + @with_transaction() + def test_init_parent(self): + "Test __init__ with _parent_" + pool = Pool() + Model = pool.get('test.model_child') + + values = { + '_parent_parent.name': "Test", + } + record = Model(**values) + + self.assertEqual(record.parent.name, "Test") + + @with_transaction() + def test_init_parent_parent(self): + "Test __init__ with _parent_._parent_" + pool = Pool() + Model = pool.get('test.model_child_child') + + values = { + '_parent_parent.name': "Test 1", + '_parent_parent._parent_parent.name': "Test 2", + } + record = Model(**values) + + self.assertEqual(record.parent.name, "Test 1") + self.assertEqual(record.parent.parent.name, "Test 2") + def suite(): return unittest.TestLoader().loadTestsFromTestCase(ModelTestCase)