diff options
| author | Raphael Collet <rco@odoo.com> | 2020-03-10 16:33:05 +0000 |
|---|---|---|
| committer | Raphael Collet <rco@odoo.com> | 2020-03-23 09:04:59 +0000 |
| commit | fd50ba9fb838067fab0b920470cf79b9c94d785c (patch) | |
| tree | 4e7ebd1736c4584fbcb168282ca49e1cf9e6c730 /odoo/addons/test_new_api | |
| parent | 8978b0bc8f335a4339e7868343a2767980d29f97 (diff) | |
[IMP] core: do not recompute stored field on new record
The use case is a cache miss of a stored field with compute on a new
record with origin. The field should be computed only when explicitly
triggered, i.e., when a dependency has been modified. Otherwise it
should be fetched from the origin record.
closes odoo/odoo#47353
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Diffstat (limited to 'odoo/addons/test_new_api')
| -rw-r--r-- | odoo/addons/test_new_api/models/test_new_api.py | 12 | ||||
| -rw-r--r-- | odoo/addons/test_new_api/tests/test_new_fields.py | 46 | ||||
| -rw-r--r-- | odoo/addons/test_new_api/tests/test_onchange.py | 28 | ||||
| -rw-r--r-- | odoo/addons/test_new_api/views/test_new_api_views.xml | 23 |
4 files changed, 109 insertions, 0 deletions
diff --git a/odoo/addons/test_new_api/models/test_new_api.py b/odoo/addons/test_new_api/models/test_new_api.py index 14a981b3b0c..9331f6eedee 100644 --- a/odoo/addons/test_new_api/models/test_new_api.py +++ b/odoo/addons/test_new_api/models/test_new_api.py @@ -796,6 +796,7 @@ class ModelChildM2o(models.Model): parent_id = fields.Many2one('test_new_api.model_parent_m2o', ondelete='cascade') size1 = fields.Integer(compute='_compute_sizes', store=True) size2 = fields.Integer(compute='_compute_sizes', store=True) + cost = fields.Integer(compute='_compute_cost', store=True, readonly=False) @api.depends('parent_id.name') def _compute_sizes(self): @@ -803,6 +804,11 @@ class ModelChildM2o(models.Model): record.size1 = len(self.parent_id.name) record.size2 = len(self.parent_id.name) + @api.depends('name') + def _compute_cost(self): + for record in self: + record.cost = len(record.name) + def write(self, vals): res = super(ModelChildM2o, self).write(vals) if self.name == 'A': @@ -816,6 +822,12 @@ class ModelParentM2o(models.Model): name = fields.Char('Name') child_ids = fields.One2many('test_new_api.model_child_m2o', 'parent_id', string="Children") + cost = fields.Integer(compute='_compute_cost', store=True) + + @api.depends('child_ids.cost') + def _compute_cost(self): + for record in self: + record.cost = sum(child.cost for child in record.child_ids) class Country(models.Model): diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py index c27704a47d9..7aa9b3c5a74 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -1090,6 +1090,52 @@ class TestFields(TransactionCaseWithUserDemo): with self.assertRaises(AccessError): cat1.name + def test_40_real_vs_new(self): + """ test field access on new records vs real records. """ + Model = self.env['test_new_api.category'] + real_record = Model.create({'name': 'Foo'}) + self.env.cache.invalidate() + new_origin = Model.new({'name': 'Bar'}, origin=real_record) + new_record = Model.new({'name': 'Baz'}) + + # non-computed non-stored field: default value + real_record = real_record.with_context(default_dummy='WTF') + new_origin = new_origin.with_context(default_dummy='WTF') + new_record = new_record.with_context(default_dummy='WTF') + self.assertEqual(real_record.dummy, 'WTF') + self.assertEqual(new_origin.dummy, 'WTF') + self.assertEqual(new_record.dummy, 'WTF') + + # non-computed stored field: origin or default if no origin + real_record = real_record.with_context(default_color=42) + new_origin = new_origin.with_context(default_color=42) + new_record = new_record.with_context(default_color=42) + self.assertEqual(real_record.color, 0) + self.assertEqual(new_origin.color, 0) + self.assertEqual(new_record.color, 42) + + # computed non-stored field: always computed + self.assertEqual(real_record.display_name, 'Foo') + self.assertEqual(new_origin.display_name, 'Bar') + self.assertEqual(new_record.display_name, 'Baz') + + # computed stored field: origin or computed if no origin + Model = self.env['test_new_api.recursive'] + real_record = Model.create({'name': 'Foo'}) + new_origin = Model.new({'name': 'Bar'}, origin=real_record) + new_record = Model.new({'name': 'Baz'}) + self.assertEqual(real_record.display_name, 'Foo') + self.assertEqual(new_origin.display_name, 'Foo') + self.assertEqual(new_record.display_name, 'Baz') + + # computed stored field with recomputation: always computed + real_record.name = 'Fool' + new_origin.name = 'Barr' + new_record.name = 'Bazz' + self.assertEqual(real_record.display_name, 'Fool') + self.assertEqual(new_origin.display_name, 'Barr') + self.assertEqual(new_record.display_name, 'Bazz') + def test_40_new_defaults(self): """ Test new records with defaults. """ user = self.env.user diff --git a/odoo/addons/test_new_api/tests/test_onchange.py b/odoo/addons/test_new_api/tests/test_onchange.py index 5d544bd2875..398bd537bbd 100644 --- a/odoo/addons/test_new_api/tests/test_onchange.py +++ b/odoo/addons/test_new_api/tests/test_onchange.py @@ -678,3 +678,31 @@ class TestComputeOnchange(common.TransactionCase): form.foo = "foo6" self.assertEqual(form.bar, "foo6") self.assertEqual(form.baz, "baz5") + + def test_onchange_one2many(self): + record = self.env['test_new_api.model_parent_m2o'].create({ + 'name': 'Family', + 'child_ids': [ + (0, 0, {'name': 'W', 'cost': 10}), + (0, 0, {'name': 'X', 'cost': 10}), + (0, 0, {'name': 'Y'}), + (0, 0, {'name': 'Z'}), + ], + }) + record.flush() + self.assertEqual(record.child_ids.mapped('name'), list('WXYZ')) + self.assertEqual(record.cost, 22) + + # modifying a line should not recompute the cost on other lines + with common.Form(record) as form: + with form.child_ids.edit(1) as line: + line.name = 'XXX' + self.assertEqual(form.cost, 15) + + with form.child_ids.edit(1) as line: + line.cost = 20 + self.assertEqual(form.cost, 32) + + with form.child_ids.edit(2) as line: + line.cost = 30 + self.assertEqual(form.cost, 61) diff --git a/odoo/addons/test_new_api/views/test_new_api_views.xml b/odoo/addons/test_new_api/views/test_new_api_views.xml index 830210c4d87..c0ed0a7baa7 100644 --- a/odoo/addons/test_new_api/views/test_new_api_views.xml +++ b/odoo/addons/test_new_api/views/test_new_api_views.xml @@ -296,5 +296,28 @@ </form> </field> </record> + + <!-- Multi form view --> + <record id="model_parent_form" model="ir.ui.view"> + <field name="name">model parent form view</field> + <field name="model">test_new_api.model_parent_m2o</field> + <field name="arch" type="xml"> + <form string="Model Parent"> + <sheet> + <group> + <field name="name"/> + <field name="cost"/> + </group> + <label for="child_ids"/> + <field name="child_ids"> + <tree string="Children" editable="bottom"> + <field name="name"/> + <field name="cost"/> + </tree> + </field> + </sheet> + </form> + </field> + </record> </data> </odoo> |
