From 8b2f887c29f4377d8ebf5a3b8e2fcd9f7660add2 Mon Sep 17 00:00:00 2001 From: Munaf Bahelim Date: Wed, 23 Feb 2022 09:44:11 +0000 Subject: [PATCH] [FIX] website_slides: better compute (dis)likes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this commit we fix computation of likes and dislikes by splitting computation by usage. Computation for likes and dislikes is improved to be done using a read_group instead of browsing potentially a lot of slide.slide.partner records. This should speedup computation, even if we have to do 2 read group instead of a single big fetch. Indeed we have to take into account vote being 1 or -1 to compute both values "like" and "dislike". We also fix batch computation as it was sharing a dict. As frontend UI leads to voting one slide at a time this should have few effect on stored values. But now batch computation is correct. User vote computation is now basically a related on user_membership_id.vote. We keep the old compute method in case it was called but computation itself is now done with the other field. Task-2607416 closes odoo/odoo#85257 X-original-commit: c5b1283862264132d0c2bb1f172c25af5d74448c Signed-off-by: Warnon Aurélien (awa) Signed-off-by: Thibault Delavallee (tde) Co-authored-by: Munaf Bahelim Co-authored-by: Thibault Delavallée --- addons/website_slides/models/slide_slide.py | 44 ++++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py index 17207b0b62a..ed99cfd752a 100644 --- a/addons/website_slides/models/slide_slide.py +++ b/addons/website_slides/models/slide_slide.py @@ -113,7 +113,8 @@ class Slide(models.Model): string='Subscribers', groups='website_slides.group_website_slides_officer', copy=False) slide_partner_ids = fields.One2many('slide.slide.partner', 'slide_id', string='Subscribers information', groups='website_slides.group_website_slides_officer', copy=False) user_membership_id = fields.Many2one( - 'slide.slide.partner', string="Subscriber information", compute='_compute_user_membership_id', compute_sudo=False, + 'slide.slide.partner', string="Subscriber information", + compute='_compute_user_membership_id', compute_sudo=False, help="Subscriber information for the current logged in user") # Quiz related fields question_ids = fields.One2many("slide.question", "slide_id", string="Questions") @@ -180,9 +181,9 @@ class Slide(models.Model): # website website_id = fields.Many2one(related='channel_id.website_id', readonly=True) date_published = fields.Datetime('Publish Date', readonly=True, tracking=False) - likes = fields.Integer('Likes', compute='_compute_user_info', store=True, compute_sudo=False) - dislikes = fields.Integer('Dislikes', compute='_compute_user_info', store=True, compute_sudo=False) - user_vote = fields.Integer('User vote', compute='_compute_user_info', compute_sudo=False) + likes = fields.Integer('Likes', compute='_compute_like_info', store=True, compute_sudo=False) + dislikes = fields.Integer('Dislikes', compute='_compute_like_info', store=True, compute_sudo=False) + user_vote = fields.Integer('User vote', compute='_compute_user_membership_id', compute_sudo=False) embed_code = fields.Html('Embed Code', readonly=True, compute='_compute_embed_code', sanitize=False) embed_code_external = fields.Html('External Embed Code', readonly=True, compute='_compute_embed_code', sanitize=False, help="Same as 'Embed Code' but used to embed the content on an external website.") @@ -264,9 +265,39 @@ class Slide(models.Model): for record in self: record.total_views = record.slide_views + record.public_views + @api.depends('slide_partner_ids.vote') + def _compute_like_info(self): + if not self.ids: + self.update({'likes': 0, 'dislikes': 0}) + return + + rg_data_like = self.env['slide.slide.partner'].sudo().read_group( + [('slide_id', 'in', self.ids), ('vote', '=', 1)], + ['slide_id'], ['slide_id'] + ) + rg_data_dislike = self.env['slide.slide.partner'].sudo().read_group( + [('slide_id', 'in', self.ids), ('vote', '=', -1)], + ['slide_id'], ['slide_id'] + ) + mapped_data_like = dict( + (rg_data['slide_id'][0], rg_data['slide_id_count']) + for rg_data in rg_data_like + ) + mapped_data_dislike = dict( + (rg_data['slide_id'][0], rg_data['slide_id_count']) + for rg_data in rg_data_dislike + ) + + for slide in self: + slide.likes = mapped_data_like.get(slide.id, 0) + slide.dislikes = mapped_data_dislike.get(slide.id, 0) + @api.depends('slide_partner_ids.vote') @api.depends_context('uid') def _compute_user_info(self): + """ Deprecated. Now computed directly by _compute_user_membership_id + for user_vote and _compute_like_info for likes / dislikes. Remove me in + master. """ default_stats = {'likes': 0, 'dislikes': 0, 'user_vote': False} if not self.ids: @@ -277,6 +308,7 @@ class Slide(models.Model): slide_partners = self.env['slide.slide.partner'].sudo().search([ ('slide_id', 'in', self.ids) ]) + for slide_partner in slide_partners: if slide_partner.vote == 1: slide_data[slide_partner.slide_id.id]['likes'] += 1 @@ -286,6 +318,7 @@ class Slide(models.Model): slide_data[slide_partner.slide_id.id]['dislikes'] += 1 if slide_partner.partner_id == self.env.user.partner_id: slide_data[slide_partner.slide_id.id]['user_vote'] = -1 + for slide in self: slide.update(slide_data[slide.id]) @@ -379,7 +412,7 @@ class Slide(models.Model): else: slide.slide_type = False - @api.depends('slide_partner_ids.partner_id') + @api.depends('slide_partner_ids.partner_id', 'slide_partner_ids.vote') @api.depends('uid') def _compute_user_membership_id(self): slide_partners = self.env['slide.slide.partner'].sudo().search([ @@ -392,6 +425,7 @@ class Slide(models.Model): (slide_partner for slide_partner in slide_partners if slide_partner.slide_id == record), self.env['slide.slide.partner'] ) + record.user_vote = record.user_membership_id.vote @api.depends('slide_category', 'google_drive_id', 'video_source_type', 'youtube_id') def _compute_embed_code(self):