From 04573a934b14b7e36ada9a6af8ba808ebeb62bf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Laukavi=C4=8Dius?= Date: Wed, 9 Feb 2022 14:50:45 +0000 Subject: [PATCH] [FIX] base: update user groups faster When users have same groups, implied_ids can be done in batches, reducing write operations considerably. Testing done: 800 users groups_id (all have same groups_id in the end) updated using old code: took ~10s to complete. With this improvement, it takes ~1.5s closes odoo/odoo#85712 X-original-commit: 81994ea628cb492fef4e62c496d4ea1ab55d9a7e Signed-off-by: Raphael Collet --- odoo/addons/base/models/res_users.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 2cd55dfbf25..5b691798ff3 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -1147,19 +1147,23 @@ class UsersImplied(models.Model): return super(UsersImplied, self).create(vals_list) def write(self, values): + if not values.get('groups_id'): + return super(UsersImplied, self).write(values) users_before = self.filtered(lambda u: u.has_group('base.group_user')) res = super(UsersImplied, self).write(values) - if values.get('groups_id'): - # add implied groups for all users - for user in self: - if not user.has_group('base.group_user') and user in users_before: - # if we demoted a user, we strip him of all its previous privileges - # (but we should not do it if we are simply adding a technical group to a portal user) - vals = {'groups_id': [Command.clear()] + values['groups_id']} - super(UsersImplied, user).write(vals) - gs = set(concat(g.trans_implied_ids for g in user.groups_id)) - vals = {'groups_id': [Command.link(g.id) for g in gs]} - super(UsersImplied, user).write(vals) + demoted_users = users_before.filtered(lambda u: not u.has_group('base.group_user')) + if demoted_users: + # demoted users are restricted to the assigned groups only + vals = {'groups_id': [Command.clear()] + values['groups_id']} + super(UsersImplied, demoted_users).write(vals) + # add implied groups for all users (in batches) + users_batch = defaultdict(self.browse) + for user in self: + users_batch[user.groups_id] += user + for groups, users in users_batch.items(): + gs = set(concat(g.trans_implied_ids for g in groups)) + vals = {'groups_id': [Command.link(g.id) for g in gs]} + super(UsersImplied, users).write(vals) return res #