[FIX] base: speedup res_partner's _compute_avatar

Group the res_partners in self by placeholder_path value before
calling __setitem__ on each group. Because placeholders are
independent from the recordset, we can set the value
of res_partner[avatar_field] to a placeholder for a recordset
of partners. When self contains lots of partners without
image_field value, this speeds up the _compute_avatar function
noticeably. This in turn speeds up stuff like loading
the Contacts KanbanView (search_read on res_partner).

Example speedup: In a database without any image for the partners,
search_read for avatar_128 with limit=80: 609ms -> 64ms.

opw-3128771

closes odoo/odoo#122884

X-original-commit: 34e97b4c65b7392576d94b870e22e74df14f9dd2
Signed-off-by: Rémy Voet <ryv@odoo.com>
This commit is contained in:
Aurelien van Delft (avd)
2023-05-30 15:39:55 +02:00
parent 4a935d3937
commit 89b4ccd3ae
+7 -2
View File
@@ -315,8 +315,13 @@ class Partner(models.Model):
def _compute_avatar(self, avatar_field, image_field):
partners_with_internal_user = self.filtered(lambda partner: partner.user_ids - partner.user_ids.filtered('share'))
super(Partner, partners_with_internal_user)._compute_avatar(avatar_field, image_field)
for partner in self - partners_with_internal_user:
partner[avatar_field] = partner[image_field] or base64.b64encode(partner._avatar_get_placeholder())
partners_without_image = (self - partners_with_internal_user).filtered(lambda p: not p[image_field])
for _, group in tools.groupby(partners_without_image, key=lambda p: p._avatar_get_placeholder_path()):
group_partners = self.env['res.partner'].concat(*group)
group_partners[avatar_field] = base64.b64encode(group_partners[0]._avatar_get_placeholder())
for partner in self - partners_with_internal_user - partners_without_image:
partner[avatar_field] = partner[image_field]
def _avatar_get_placeholder_path(self):
if self.is_company: