Fill the source value of fmany2one in create and write methods

We can not rely on the Function field setter to set the value because it may be
too late if the source field is required and for composite key, a partial
update may not be a valid foreign key.

Closes #13522
This commit is contained in:
Cédric Krier committed 2024-09-19 13:31:59 +02:00
1 parent 513043dd6a
commit f147c94118
1 file changed
+26 -7
+26 -7
View File
@@ -17,6 +17,12 @@ def fmany2one(
target_fields = target_fields.split(',')
assert len(sources) == len(target_fields)
def convert_value(value):
pool = Pool()
Target = pool.get(target_model)
if isinstance(value, int):
return getattr(Target(value), target_fields[0])
class Mixin:
__slots__ = ()
@@ -30,6 +36,25 @@ def fmany2one(
sources, Target._table, target_fields,
on_delete=getattr(cls, name).ondelete)
@classmethod
def create(cls, vlist):
vlist = [v.copy() for v in vlist]
for values in vlist:
if name in values:
values[sources[0]] = convert_value(values.pop(name))
return super().create(vlist)
@classmethod
def write(cls, *args):
actions = iter(args)
args = []
for records, values in zip(actions, actions):
if name in values:
values = values.copy()
values[sources[0]] = convert_value(values.pop(name))
args.extend((records, values))
super().write(*args)
@classmethod
def getter(cls, records, name):
pool = Pool()
@@ -51,13 +76,7 @@ def fmany2one(
@classmethod
def setter(cls, records, name, value):
pool = Pool()
Target = pool.get(target_model)
if value:
value = getattr(Target(value), target_fields[0])
else:
value = None
cls.write(records, {sources[0]: value})
cls.write(records, {sources[0]: convert_value(value)})
@classmethod
def searcher(cls, clause, tables):