Include the depends of the getter function when depending on a Function field

Since c47b3642f1a6, the getter of a Function field may be called if there is no
value set for it on the instance.
In the on_change context, this may set the missing fields to None if they were
not defined in the depends of the method called. In addition to compute a wrong
value, those fields are then returned as modified.

Closes #13735
(grafted from 1b815539165a1212fc5c415c8920d8f5f0c55236)

--HG--
branch : 6.0
This commit is contained in:
Cédric Krier
2024-12-05 16:25:16 +01:00
parent c0d07f0615
commit 2ededea81f
2 changed files with 35 additions and 0 deletions
+12
View File
@@ -179,6 +179,18 @@ class ModelView(Model):
meth_names = list(methods['depend_methods'][function_name])
meth_done = set()
for depend in getattr(field, attribute):
if '.' in depend:
depend, _ = depend.split('.', 1)
if depend.startswith('_parent_'):
depend = depend[len('_parent_'):]
dep_field = getattr(cls, depend, None)
if dep_field:
if (isinstance(dep_field, fields.Function)
and dep_field.getter.startswith('on_change_with')):
meth_names.append(dep_field.getter)
while meth_names:
meth_name = meth_names.pop()
method = getattr(cls, meth_name)
@@ -248,6 +248,29 @@ class FieldDependsTestCase(unittest.TestCase):
self.assertEqual(Model.bar.on_change, {'foo', 'bar'})
def test_depends_function_getter(self):
"Tests depends on Function field with on_change_with getter"
class Model(ModelView):
__name__ = 'test.modelview.function_getter_depends'
test = fields.Char("Test")
foo = fields.Function(fields.Char("Foo"), 'on_change_with_foo')
bar = fields.Char("Bar")
@fields.depends('foo')
def on_change_test(self):
pass
@fields.depends('bar')
def on_change_with_foo(self, name=None):
pass
Model.__setup__()
Model.__post_setup__()
self.assertEqual(Model.test.on_change, {'foo', 'bar'})
def suite():
return unittest.TestLoader().loadTestsFromTestCase(FieldDependsTestCase)