[IMP] website_forum: optimize query
Optimize queries Fix multi-forum / mutliwebsite in child count Use stored field when possible Avoid forum count on each request (rarely updated) closes odoo/odoo#52539 Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
This commit is contained in:
@@ -654,7 +654,7 @@ class Website(models.Model):
|
||||
|
||||
@api.model
|
||||
def is_public_user(self):
|
||||
return request.env.user.id == request.website.user_id.id
|
||||
return request.env.user.id == request.website._get_cached('user_id')
|
||||
|
||||
@api.model
|
||||
def viewref(self, view_id, raise_if_not_found=True):
|
||||
|
||||
@@ -235,8 +235,6 @@ class WebsiteForum(WebsiteProfile):
|
||||
if question.state == 'pending' and user.karma < forum.karma_post and question.create_uid != user:
|
||||
raise werkzeug.exceptions.NotFound()
|
||||
|
||||
# increment view counter
|
||||
question.sudo().set_viewed()
|
||||
if question.parent_id:
|
||||
redirect_url = "/forum/%s/question/%s" % (slug(forum), slug(question.parent_id))
|
||||
return werkzeug.utils.redirect(redirect_url, 301)
|
||||
@@ -245,13 +243,17 @@ class WebsiteForum(WebsiteProfile):
|
||||
values.update({
|
||||
'main_object': question,
|
||||
'question': question,
|
||||
'can_bump': (question.forum_id.allow_bump and not question.child_ids and (datetime.today() - question.write_date).days > 9),
|
||||
'can_bump': (question.forum_id.allow_bump and not question.child_count and (datetime.today() - question.write_date).days > 9),
|
||||
'header': {'question_data': True},
|
||||
'filters': filters,
|
||||
'reversed': reversed,
|
||||
})
|
||||
if (request.httprequest.referrer or "").startswith(request.httprequest.url_root):
|
||||
values['back_button_url'] = request.httprequest.referrer
|
||||
|
||||
# increment view counter
|
||||
question.sudo().set_viewed()
|
||||
|
||||
return request.render("website_forum.post_description_full", values)
|
||||
|
||||
@http.route('/forum/<model("forum.forum"):forum>/question/<model("forum.post"):question>/toggle_favourite', type='json', auth="user", methods=['POST'], website=True)
|
||||
|
||||
@@ -177,7 +177,7 @@ class Forum(models.Model):
|
||||
@api.model
|
||||
def create(self, values):
|
||||
res = super(Forum, self.with_context(mail_create_nolog=True, mail_create_nosubscribe=True)).create(values)
|
||||
res._set_default_faq()
|
||||
res._set_default_faq() # will trigger a write and call update_website_count
|
||||
return res
|
||||
|
||||
def write(self, vals):
|
||||
@@ -199,8 +199,15 @@ class Forum(models.Model):
|
||||
if 'active' in vals:
|
||||
# archiving/unarchiving a forum does it on its posts, too
|
||||
self.env['forum.post'].with_context(active_test=False).search([('forum_id', 'in', self.ids)]).write({'active': vals['active']})
|
||||
|
||||
if 'active' in vals or 'website_id' in vals:
|
||||
self._update_website_count()
|
||||
return res
|
||||
|
||||
def unlink(self):
|
||||
self._update_website_count()
|
||||
return super(Forum, self).unlink()
|
||||
|
||||
@api.model
|
||||
def _tag_to_write_vals(self, tags=''):
|
||||
Tag = self.env['forum.tag']
|
||||
@@ -238,6 +245,12 @@ class Forum(models.Model):
|
||||
'url': self._compute_website_url(),
|
||||
}
|
||||
|
||||
@api.model
|
||||
def _update_website_count(self):
|
||||
for website in self.env['website'].sudo().search([]):
|
||||
website.forums_count = self.env['forum.forum'].sudo().search_count(website.website_domain())
|
||||
|
||||
|
||||
class Post(models.Model):
|
||||
|
||||
_name = 'forum.post'
|
||||
@@ -281,7 +294,7 @@ class Post(models.Model):
|
||||
is_correct = fields.Boolean('Correct', help='Correct answer or answer accepted')
|
||||
parent_id = fields.Many2one('forum.post', string='Question', ondelete='cascade', readonly=True, index=True)
|
||||
self_reply = fields.Boolean('Reply to own question', compute='_is_self_reply', store=True)
|
||||
child_ids = fields.One2many('forum.post', 'parent_id', string='Post Answers')
|
||||
child_ids = fields.One2many('forum.post', 'parent_id', string='Post Answers', domain=lambda self: [('forum_id', '=', self.forum_id.id)])
|
||||
child_count = fields.Integer('Answers', compute='_get_child_count', store=True)
|
||||
uid_has_answered = fields.Boolean('Has Answered', compute='_get_uid_has_answered')
|
||||
has_validated_answer = fields.Boolean('Is answered', compute='_get_has_validated_answer', store=True)
|
||||
@@ -401,7 +414,7 @@ class Post(models.Model):
|
||||
|
||||
def _get_uid_has_answered(self):
|
||||
for post in self:
|
||||
post.uid_has_answered = any(answer.create_uid.id == post._uid for answer in post.child_ids)
|
||||
post.uid_has_answered = post._uid in post.child_ids.create_uid.ids
|
||||
|
||||
@api.depends('child_ids.is_correct')
|
||||
def _get_has_validated_answer(self):
|
||||
@@ -838,7 +851,8 @@ class Post(models.Model):
|
||||
return result
|
||||
|
||||
def set_viewed(self):
|
||||
self._cr.execute("""UPDATE forum_post SET views = views+1 WHERE id IN %s""", (self._ids,))
|
||||
self.ensure_one()
|
||||
self._cr.execute("""UPDATE forum_post SET views = views+1 WHERE views = %s and id = %s""", (self.views, self.id,))
|
||||
return True
|
||||
|
||||
def get_access_action(self, access_uid=None):
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields, _
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.addons.http_routing.models.ir_http import url_for
|
||||
|
||||
|
||||
class Website(models.Model):
|
||||
_inherit = 'website'
|
||||
|
||||
def _compute_field_forums_count(self):
|
||||
Forum = self.env['forum.forum']
|
||||
for website in self:
|
||||
website.forums_count = Forum.search_count(website.website_domain())
|
||||
@api.model
|
||||
def get_default_forum_count(self):
|
||||
self.forums_count = self.env['forum.forum'].search_count(self.website_domain())
|
||||
|
||||
forums_count = fields.Integer(compute=_compute_field_forums_count)
|
||||
forums_count = fields.Integer(readonly=True, default=get_default_forum_count)
|
||||
|
||||
def get_suggested_controllers(self):
|
||||
suggested_controllers = super(Website, self).get_suggested_controllers()
|
||||
|
||||
@@ -288,7 +288,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<span class="mx-1 d-none d-sm-inline">&nbsp;|</span>
|
||||
<a t-if="len(question.child_ids)>0" class="font-weight-bold" t-attf-href="/forum/#{ slug(question.forum_id) }/question/#{ slug(question) }">
|
||||
<a t-if="question.child_count" class="font-weight-bold" t-attf-href="/forum/#{ slug(question.forum_id) }/question/#{ slug(question) }">
|
||||
<t t-esc="question.child_count"/>
|
||||
<t t-if="question.child_count == 1">Answer</t>
|
||||
<t t-else="">Answers</t>
|
||||
@@ -1181,10 +1181,10 @@
|
||||
<t t-set="_collapse_uid" t-value="_question_comment_collapse_uid"/>
|
||||
</t>
|
||||
|
||||
<section t-if="question.child_ids" t-attf-class="#{question.website_message_ids and 'mt-5' or 'mt-4'}">
|
||||
<section t-if="question.child_count" t-attf-class="#{question.website_message_ids and 'mt-5' or 'mt-4'}">
|
||||
<h5>
|
||||
<t t-esc="len(question.child_ids)"/>
|
||||
<t t-if="len(question.child_ids) == 1">Answer</t>
|
||||
<t t-esc="question.child_count"/>
|
||||
<t t-if="question.child_count == 1">Answer</t>
|
||||
<t t-else="">Answers</t>
|
||||
</h5>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user