[FIX] models: implement change_default behavior for fields

The behavior is no longer implemented by the web client.  Implement it
server-side as part of the onchange mechanism, simply by defining onchange
methods for the fields that have the flag.
This commit is contained in:
Raphael Collet
2017-08-24 09:37:55 +02:00
parent d8c897de64
commit 32aa7dc9a0
3 changed files with 35 additions and 1 deletions
+1 -1
View File
@@ -286,7 +286,7 @@ class Foo(models.Model):
_name = 'test_new_api.foo'
name = fields.Char()
value1 = fields.Integer()
value1 = fields.Integer(change_default=True)
value2 = fields.Integer()
@@ -231,6 +231,28 @@ class TestOnChange(common.TransactionCase):
for user in discussion.participants + demo],
)
def test_onchange_default(self):
""" test the effect of a conditional user-default on a field """
Foo = self.env['test_new_api.foo']
field_onchange = Foo._onchange_spec()
self.assertTrue(Foo._fields['value1'].change_default)
self.assertEqual(field_onchange.get('value1'), '1')
# create a user-defined default based on 'value1'
self.env['ir.values'].set_default('test_new_api.foo', 'value2', 666, condition='value1=42')
# setting 'value1' to 42 should trigger the change of 'value2'
self.env.invalidate_all()
values = {'name': 'X', 'value1': 42, 'value2': False}
result = Foo.onchange(values, 'value1', field_onchange)
self.assertEqual(result['value'], {'value2': 666})
# setting 'value1' to 24 should not trigger the change of 'value2'
self.env.invalidate_all()
values = {'name': 'X', 'value1': 24, 'value2': False}
result = Foo.onchange(values, 'value1', field_onchange)
self.assertEqual(result['value'], {})
def test_onchange_one2many_value(self):
""" test the value of the one2many field inside the onchange """
discussion = self.env.ref('test_new_api.discussion_0')
+12
View File
@@ -573,6 +573,7 @@ class BaseModel(object):
def is_onchange(func):
return callable(func) and hasattr(func, '_onchange')
# collect onchange methods on the model's class
cls = type(self)
methods = defaultdict(list)
for attr, func in getmembers(cls, is_onchange):
@@ -581,6 +582,17 @@ class BaseModel(object):
_logger.warning("@onchange%r parameters must be field names", func._onchange)
methods[name].append(func)
# add onchange methods to implement "change_default" on fields
def onchange_default(field, self):
value = field.convert_to_write(self[field.name], self)
condition = "%s=%s" % (field.name, value)
defaults = self.env['ir.values'].get_defaults_dict(self._name, condition)
self.update(defaults)
for name, field in cls._fields.items():
if field.change_default:
methods[name].append(functools.partial(onchange_default, field))
# optimization: memoize result on cls, it will not be recomputed
cls._onchange_methods = methods
return methods