changeset f6615c7c6c21 in trytond:default details: https://hg.tryton.org/trytond?cmd=changeset;node=f6615c7c6c21 description: Update MPTT only for affected fields
issue10130 review353331002 diffstat: trytond/model/modelsql.py | 89 +++++++++++++++++++++--------------------- trytond/model/modelstorage.py | 11 +++++ 2 files changed, 55 insertions(+), 45 deletions(-) diffs (151 lines): diff -r 318efe295241 -r f6615c7c6c21 trytond/model/modelsql.py --- a/trytond/model/modelsql.py Tue Mar 02 08:38:10 2021 +0100 +++ b/trytond/model/modelsql.py Fri Mar 05 18:22:55 2021 +0100 @@ -1,7 +1,7 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import datetime -from itertools import islice, chain, product, groupby +from itertools import islice, chain, product, groupby, repeat from collections import OrderedDict, defaultdict from functools import wraps @@ -665,8 +665,9 @@ cls._insert_history(new_ids) - field_names = list(cls._fields.keys()) - cls._update_mptt(field_names, [new_ids] * len(field_names)) + if cls._mptt_fields: + field_names = list(sorted(cls._mptt_fields)) + cls._update_mptt(field_names, repeat(new_ids, len(field_names))) cls.__check_domain_rule(new_ids, 'create') records = cls.browse(new_ids) @@ -1027,9 +1028,12 @@ if hasattr(field, 'set'): fields_to_set.setdefault(fname, []).extend((ids, value)) - field_names = list(values.keys()) - cls._update_mptt(field_names, [ids] * len(field_names), values) - all_field_names |= set(field_names) + mptt_fields = cls._mptt_fields & set(values) + if mptt_fields: + cls._update_mptt( + list(sorted(mptt_fields)), repeat(ids, len(mptt_fields)), + values) + all_field_names |= set(values) for fname in sorted(fields_to_set, key=cls.index_set_field): fargs = fields_to_set[fname] @@ -1067,20 +1071,18 @@ cls.__check_timestamp(ids) cls.__check_domain_rule(ids, 'delete') - has_translation = False tree_ids = {} - for fname, field in cls._fields.items(): - if (isinstance(field, fields.Many2One) - and field.model_name == cls.__name__ - and field.left and field.right): - tree_ids[fname] = [] - for sub_ids in grouped_slice(ids): - where = reduce_ids(field.sql_column(table), sub_ids) - cursor.execute(*table.select(table.id, where=where)) - tree_ids[fname] += [x[0] for x in cursor.fetchall()] - if (getattr(field, 'translate', False) - and not hasattr(field, 'set')): - has_translation = True + for fname in cls._mptt_fields: + field = cls._fields[fname] + tree_ids[fname] = [] + for sub_ids in grouped_slice(ids): + where = reduce_ids(field.sql_column(table), sub_ids) + cursor.execute(*table.select(table.id, where=where)) + tree_ids[fname] += [x[0] for x in cursor.fetchall()] + + has_translation = any( + getattr(f, 'translate', False) and not hasattr(f, 'set') + for f in cls._fields.values()) foreign_keys_tocheck = [] foreign_keys_toupdate = [] @@ -1463,34 +1465,31 @@ cursor = Transaction().connection.cursor() for field_name, ids in zip(field_names, list_ids): field = cls._fields[field_name] - if (isinstance(field, fields.Many2One) - and field.model_name == cls.__name__ - and field.left and field.right): - if (values is not None - and (field.left in values or field.right in values)): - raise Exception('ValidateError', - 'You can not update fields: "%s", "%s"' % - (field.left, field.right)) + if (values is not None + and (field.left in values or field.right in values)): + raise Exception('ValidateError', + 'You can not update fields: "%s", "%s"' % + (field.left, field.right)) - # Nested creation require a rebuild - # because initial values are 0 - # and thus _update_tree can not find the children - table = cls.__table__() - parent = cls.__table__() - cursor.execute(*table.join(parent, - condition=Column(table, field_name) == parent.id - ).select(table.id, - where=(Column(parent, field.left) == 0) - & (Column(parent, field.right) == 0), - limit=1)) - nested_create = cursor.fetchone() + # Nested creation require a rebuild + # because initial values are 0 + # and thus _update_tree can not find the children + table = cls.__table__() + parent = cls.__table__() + cursor.execute(*table.join(parent, + condition=Column(table, field_name) == parent.id + ).select(table.id, + where=(Column(parent, field.left) == 0) + & (Column(parent, field.right) == 0), + limit=1)) + nested_create = cursor.fetchone() - if not nested_create and len(ids) < 2: - for id_ in ids: - cls._update_tree(id_, field_name, - field.left, field.right) - else: - cls._rebuild_tree(field_name, None, 0) + if not nested_create and len(ids) < 2: + for id_ in ids: + cls._update_tree(id_, field_name, + field.left, field.right) + else: + cls._rebuild_tree(field_name, None, 0) @classmethod def _rebuild_tree(cls, parent, parent_id, left): diff -r 318efe295241 -r f6615c7c6c21 trytond/model/modelstorage.py --- a/trytond/model/modelstorage.py Tue Mar 02 08:38:10 2021 +0100 +++ b/trytond/model/modelstorage.py Fri Mar 05 18:22:55 2021 +0100 @@ -141,6 +141,17 @@ 'import_data': RPC(readonly=False), }) + @classmethod + def __post_setup__(cls): + super().__post_setup__() + + cls._mptt_fields = set() + for name, field in cls._fields.items(): + if (isinstance(field, fields.Many2One) + and field.model_name == cls.__name__ + and field.left and field.right): + cls._mptt_fields.add(name) + @staticmethod def default_create_uid(): "Default value for uid field."