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
This commit is contained in:
Cédric Krier
2024-12-05 16:25:16 +01:00
parent 1360ae6c5d
commit 4cbce5729e
2 changed files with 34 additions and 0 deletions
+11
View File
@@ -150,6 +150,17 @@ 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_'):]
if dep_field := getattr(cls, depend, None):
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)
@@ -263,3 +263,26 @@ class FieldDependsTestCase(TestCase):
]:
with self.subTest(value=value):
self.assertEqual(fields.get_eval_fields(value), result)
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'})