[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 <rco@odoo.com>
This commit is contained in:
Andrius Laukavičius
2022-03-03 11:04:21 +00:00
committed by Raphael Collet
parent 4627e83d4b
commit 04573a934b
+15 -11
View File
@@ -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
#