summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphael Collet <rco@odoo.com>2019-04-11 07:19:38 +0000
committerRaphael Collet <rco@odoo.com>2019-05-20 11:00:40 +0000
commit6ad43a44a2fd254c8f768003e6d2f12816eb017e (patch)
tree79a2d8d76cb3e67f4a735eaf3918f0891e9a400f
parent7f1a1fee49ec37fd4e5fb9506ba9ccdb5528dc0b (diff)
[IMP] models: new records return default values
-rw-r--r--odoo/addons/test_new_api/tests/test_new_fields.py39
-rw-r--r--odoo/fields.py20
2 files changed, 40 insertions, 19 deletions
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 578ad04d6f1..de9bc11dcaf 100644
--- a/odoo/addons/test_new_api/tests/test_new_fields.py
+++ b/odoo/addons/test_new_api/tests/test_new_fields.py
@@ -928,25 +928,38 @@ class TestFields(common.TransactionCase):
with self.assertRaises(AccessError):
cat1.name
- def test_40_new(self):
- """ test new records. """
+ def test_40_new_defaults(self):
+ """ Test new records with defaults. """
+ user = self.env.user
discussion = self.env.ref('test_new_api.discussion_0')
- # create a new message
- message = self.env['test_new_api.message'].new()
- self.assertFalse(message.id)
+ # create a new message; fields have their default value if not given
+ new_msg = self.env['test_new_api.message'].new({'body': "XXX"})
+ self.assertFalse(new_msg.id)
+ self.assertEqual(new_msg.body, "XXX")
+ self.assertEqual(new_msg.author, user)
# assign some fields; should have no side effect
- message.discussion = discussion
- message.body = BODY = "May the Force be with you."
- self.assertEqual(message.discussion, discussion)
- self.assertEqual(message.body, BODY)
- self.assertFalse(message.author)
- self.assertNotIn(message, discussion.messages)
+ new_msg.discussion = discussion
+ new_msg.body = "YYY"
+ self.assertEqual(new_msg.discussion, discussion)
+ self.assertEqual(new_msg.body, "YYY")
+ self.assertNotIn(new_msg, discussion.messages)
# check computed values of fields
- self.assertEqual(message.name, "[%s] %s" % (discussion.name, ''))
- self.assertEqual(message.size, len(BODY))
+ self.assertEqual(new_msg.name, "[%s] %s" % (discussion.name, user.name))
+ self.assertEqual(new_msg.size, 3)
+
+ # extra tests for x2many fields with default
+ cat1 = self.env['test_new_api.category'].create({'name': "Cat1"})
+ cat2 = self.env['test_new_api.category'].create({'name': "Cat2"})
+ discussion = discussion.with_context(default_categories=[(4, cat1.id)])
+ # no value gives the default value
+ new_disc = discussion.new({'name': "Foo"})
+ self.assertEqual(new_disc.categories, cat1)
+ # value is combined with default value
+ new_disc = discussion.new({'name': "Foo", 'categories': [(4, cat2.id)]})
+ self.assertEqual(new_disc.categories, cat1 + cat2)
@mute_logger('odoo.addons.base.models.ir_model')
def test_41_new_related(self):
diff --git a/odoo/fields.py b/odoo/fields.py
index db533ecbb51..25cdcfe1adb 100644
--- a/odoo/fields.py
+++ b/odoo/fields.py
@@ -1116,12 +1116,20 @@ class Field(MetaField('DummyField', (object,), {})):
def determine_draft_value(self, record):
""" Determine the value of ``self`` for the given draft ``record``. """
if self.compute:
- fields = record._field_computed[self]
- with record.env.protecting(fields, record):
- self._compute_value(record)
- else:
- null = self.convert_to_cache(False, record, validate=False)
- record.env.cache.set_special(record, self, lambda: null)
+ return self.compute_value(record)
+
+ null = self.convert_to_cache(False, record, validate=False)
+ record.env.cache.set_special(record, self, lambda: null)
+
+ defaults = record.default_get([self.name])
+ if self.name in defaults:
+ # The null value above is necessary to convert x2many field values.
+ # For instance, converting [(4, id)] accesses the field's current
+ # value, then adds the given id. Without an initial value, the
+ # conversion ends up here to determine the field's value, and this
+ # generates an infinite recursion.
+ value = self.convert_to_cache(defaults[self.name], record)
+ return record.env.cache.set(record, self, value)
def determine_inverse(self, records):
""" Given the value of ``self`` on ``records``, inverse the computation. """