[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:
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user