details: https://code.tryton.org/tryton/commit/6af5c937a3ce
branch: default
user: Cédric Krier <[email protected]>
date: Tue Feb 24 11:34:42 2026 +0100
description:
Support fmany2one based on Function fields
diffstat:
trytond/CHANGELOG | 1 +
trytond/trytond/model/fields/fmany2one.py | 25 ++++++++++++++++++++-----
2 files changed, 21 insertions(+), 5 deletions(-)
diffs (51 lines):
diff -r 975bcdbbc785 -r 6af5c937a3ce trytond/CHANGELOG
--- a/trytond/CHANGELOG Tue Feb 24 09:19:37 2026 +0100
+++ b/trytond/CHANGELOG Tue Feb 24 11:34:42 2026 +0100
@@ -1,3 +1,4 @@
+* Support fmany2one based on Function fields
* Add timestamp field on ModelSQL for last modified
* Support Function field without getter but SQL expression
* Add support for column_<field name> method
diff -r 975bcdbbc785 -r 6af5c937a3ce trytond/trytond/model/fields/fmany2one.py
--- a/trytond/trytond/model/fields/fmany2one.py Tue Feb 24 09:19:37 2026 +0100
+++ b/trytond/trytond/model/fields/fmany2one.py Tue Feb 24 11:34:42 2026 +0100
@@ -31,10 +31,22 @@
pool = Pool()
Target = pool.get(target_model)
table_h = cls.__table_handler__(module)
+ target_h = Target.__table_handler__(module)
super().__register__(module)
- table_h.add_fk(
- sources, Target._table, target_fields,
- on_delete=getattr(cls, name).ondelete)
+ if (all(table_h.column_exist(s) for s in sources)
+ and all(target_h.column_exist(t) for t in target_fields)):
+ table_h.add_fk(
+ sources, Target._table, target_fields,
+ on_delete=getattr(cls, name).ondelete)
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ if any(isinstance(getattr(cls, s), Function) for s in sources):
+ try:
+ delattr(Mixin, f'domain_{name}')
+ except AttributeError:
+ pass
@classmethod
def preprocess_values(cls, mode, values):
@@ -92,8 +104,11 @@
setattr(Mixin, name, Function(
Many2One(target_model, string, ondelete=ondelete, **kwargs),
- f'get_{name}', setter=f'set_{name}'))
+ f'get_{name}',
+ setter=f'set_{name}'
+ if not kwargs.get('readonly', False) else None))
setattr(Mixin, f'get_{name}', getter)
- setattr(Mixin, f'set_{name}', setter)
+ if not kwargs.get('readonly', False):
+ setattr(Mixin, f'set_{name}', setter)
setattr(Mixin, f'domain_{name}', searcher)
return Mixin