[IMP] website_forum: performance improvements

- avoid to browse on every question/answer, only the 20 most recent ones (need to manually update the view to see the real number of q&a)
- do not render hidden tabs (leakage of information and useless rendering)
- add related fields to speed up vote search (need to be stored to be efficient)
This commit is contained in:
Martin Trigaux 2014-09-02 16:24:26 +02:00
parent 8d23a3a86c
commit 78fa861936
3 changed files with 34 additions and 25 deletions

View File

@ -451,16 +451,21 @@ class WebsiteForum(http.Controller):
return request.website.render("website_forum.private_profile", values) return request.website.render("website_forum.private_profile", values)
# questions and answers by user # questions and answers by user
user_questions, user_answers = [], [] user_questions, user_answers = [], []
user_post_ids = Post.search( user_question_ids = Post.search(cr, uid, [
cr, uid, [ ('parent_id', '=', False),
('forum_id', '=', forum.id), ('create_uid', '=', user.id), ('forum_id', '=', forum.id), ('create_uid', '=', user.id),
'|', ('active', '=', False), ('active', '=', True)], context=context) ], order='create_date desc', context=context)
user_posts = Post.browse(cr, uid, user_post_ids, context=context) count_user_questions = len(user_question_ids)
for record in user_posts: # displaying only the 20 most recent questions
if record.parent_id: user_questions = Post.browse(cr, uid, user_question_ids[:20], context=context)
user_answers.append(record)
else: user_answer_ids = Post.search(cr, uid, [
user_questions.append(record) ('parent_id', '!=', False),
('forum_id', '=', forum.id), ('create_uid', '=', user.id),
], order='create_date desc', context=context)
count_user_answers = len(user_answer_ids)
# displaying only the 20 most recent answers
user_answers = Post.browse(cr, uid, user_answer_ids[:20], context=context)
# showing questions which user following # showing questions which user following
obj_ids = Followers.search(cr, SUPERUSER_ID, [('res_model', '=', 'forum.post'), ('partner_id', '=', user.partner_id.id)], context=context) obj_ids = Followers.search(cr, SUPERUSER_ID, [('res_model', '=', 'forum.post'), ('partner_id', '=', user.partner_id.id)], context=context)
@ -473,14 +478,13 @@ class WebsiteForum(http.Controller):
favourite = Post.browse(cr, uid, fav_que_ids, context=context) favourite = Post.browse(cr, uid, fav_que_ids, context=context)
#votes which given on users questions and answers. #votes which given on users questions and answers.
data = Vote.read_group(cr, uid, [('post_id.forum_id', '=', forum.id), ('post_id.create_uid', '=', user.id)], ["vote"], groupby=["vote"], context=context) data = Vote.read_group(cr, uid, [('forum_id', '=', forum.id), ('recipient_id', '=', user.id)], ["vote"], groupby=["vote"], context=context)
up_votes, down_votes = 0, 0 up_votes, down_votes = 0, 0
for rec in data: for rec in data:
if rec['vote'] == '1': if rec['vote'] == '1':
up_votes = rec['vote_count'] up_votes = rec['vote_count']
elif rec['vote'] == '-1': elif rec['vote'] == '-1':
down_votes = rec['vote_count'] down_votes = rec['vote_count']
total_votes = up_votes + down_votes
#Votes which given by users on others questions and answers. #Votes which given by users on others questions and answers.
post_votes = Vote.search(cr, uid, [('user_id', '=', user.id)], context=context) post_votes = Vote.search(cr, uid, [('user_id', '=', user.id)], context=context)
@ -488,7 +492,7 @@ class WebsiteForum(http.Controller):
#activity by user. #activity by user.
model, comment = Data.get_object_reference(cr, uid, 'mail', 'mt_comment') model, comment = Data.get_object_reference(cr, uid, 'mail', 'mt_comment')
activity_ids = Activity.search(cr, uid, [('res_id', 'in', user_post_ids), ('model', '=', 'forum.post'), ('subtype_id', '!=', comment)], order='date DESC', limit=100, context=context) activity_ids = Activity.search(cr, uid, [('res_id', 'in', user_question_ids+user_answer_ids), ('model', '=', 'forum.post'), ('subtype_id', '!=', comment)], order='date DESC', limit=100, context=context)
activities = Activity.browse(cr, uid, activity_ids, context=context) activities = Activity.browse(cr, uid, activity_ids, context=context)
posts = {} posts = {}
@ -509,10 +513,11 @@ class WebsiteForum(http.Controller):
'main_object': user, 'main_object': user,
'searches': post, 'searches': post,
'questions': user_questions, 'questions': user_questions,
'count_questions': count_user_questions,
'answers': user_answers, 'answers': user_answers,
'count_answers': count_user_answers,
'followed': followed, 'followed': followed,
'favourite': favourite, 'favourite': favourite,
'total_votes': total_votes,
'up_votes': up_votes, 'up_votes': up_votes,
'down_votes': down_votes, 'down_votes': down_votes,
'activities': activities, 'activities': activities,

View File

@ -526,6 +526,10 @@ class Vote(osv.Model):
'user_id': fields.many2one('res.users', 'User', required=True), 'user_id': fields.many2one('res.users', 'User', required=True),
'vote': fields.selection([('1', '1'), ('-1', '-1'), ('0', '0')], 'Vote', required=True), 'vote': fields.selection([('1', '1'), ('-1', '-1'), ('0', '0')], 'Vote', required=True),
'create_date': fields.datetime('Create Date', select=True, readonly=True), 'create_date': fields.datetime('Create Date', select=True, readonly=True),
# TODO master: store these two
'forum_id': fields.related('post_id', 'forum_id', type='many2one', relation='forum.forum', string='Forum'),
'recipient_id': fields.related('post_id', 'create_uid', type='many2one', relation='res.users', string='To', help="The user receiving the vote"),
} }
_defaults = { _defaults = {
'user_id': lambda self, cr, uid, ctx: uid, 'user_id': lambda self, cr, uid, ctx: uid,
@ -544,20 +548,20 @@ class Vote(osv.Model):
vote_id = super(Vote, self).create(cr, uid, vals, context=context) vote_id = super(Vote, self).create(cr, uid, vals, context=context)
vote = self.browse(cr, uid, vote_id, context=context) vote = self.browse(cr, uid, vote_id, context=context)
if vote.post_id.parent_id: if vote.post_id.parent_id:
karma_value = self._get_karma_value('0', vote.vote, vote.post_id.forum_id.karma_gen_answer_upvote, vote.post_id.forum_id.karma_gen_answer_downvote) karma_value = self._get_karma_value('0', vote.vote, vote.forum_id.karma_gen_answer_upvote, vote.forum_id.karma_gen_answer_downvote)
else: else:
karma_value = self._get_karma_value('0', vote.vote, vote.post_id.forum_id.karma_gen_question_upvote, vote.post_id.forum_id.karma_gen_question_downvote) karma_value = self._get_karma_value('0', vote.vote, vote.forum_id.karma_gen_question_upvote, vote.forum_id.karma_gen_question_downvote)
self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [vote.post_id.create_uid.id], karma_value, context=context) self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [vote.recipient_id.id], karma_value, context=context)
return vote_id return vote_id
def write(self, cr, uid, ids, values, context=None): def write(self, cr, uid, ids, values, context=None):
if 'vote' in values: if 'vote' in values:
for vote in self.browse(cr, uid, ids, context=context): for vote in self.browse(cr, uid, ids, context=context):
if vote.post_id.parent_id: if vote.post_id.parent_id:
karma_value = self._get_karma_value(vote.vote, values['vote'], vote.post_id.forum_id.karma_gen_answer_upvote, vote.post_id.forum_id.karma_gen_answer_downvote) karma_value = self._get_karma_value(vote.vote, values['vote'], vote.forum_id.karma_gen_answer_upvote, vote.forum_id.karma_gen_answer_downvote)
else: else:
karma_value = self._get_karma_value(vote.vote, values['vote'], vote.post_id.forum_id.karma_gen_question_upvote, vote.post_id.forum_id.karma_gen_question_downvote) karma_value = self._get_karma_value(vote.vote, values['vote'], vote.forum_id.karma_gen_question_upvote, vote.forum_id.karma_gen_question_downvote)
self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [vote.post_id.create_uid.id], karma_value, context=context) self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [vote.recipient_id.id], karma_value, context=context)
res = super(Vote, self).write(cr, uid, ids, values, context=context) res = super(Vote, self).write(cr, uid, ids, values, context=context)
return res return res

View File

@ -963,10 +963,10 @@
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"> <li class="active">
<a href="#questions" data-toggle="tab"><t t-esc="len(questions)"/> Questions</a> <a href="#questions" data-toggle="tab"><t t-esc="count_questions"/> Questions</a>
</li> </li>
<li> <li>
<a href="#answers" data-toggle="tab"><t t-esc="len(answers)"/> Answers</a> <a href="#answers" data-toggle="tab"><t t-esc="count_answers"/> Answers</a>
</li> </li>
<li t-if="uid == user.id"> <li t-if="uid == user.id">
<a href="#favourite_question" data-toggle="tab"><t t-esc="len(favourite)"/> Favourite Questions</a> <a href="#favourite_question" data-toggle="tab"><t t-esc="len(favourite)"/> Favourite Questions</a>
@ -1000,20 +1000,20 @@
<div class="tab-pane" id="badges"> <div class="tab-pane" id="badges">
<t t-call="website_forum.user_badges"/> <t t-call="website_forum.user_badges"/>
</div> </div>
<div class="tab-pane" id="favourite_question"> <div class="tab-pane" id="favourite_question" t-if="uid == user.id">
<div t-foreach="favourite" t-as="question"> <div t-foreach="favourite" t-as="question">
<t t-call="website_forum.display_post"/> <t t-call="website_forum.display_post"/>
</div> </div>
</div> </div>
<div class="tab-pane" id="followed_question"> <div class="tab-pane" id="followed_question" t-if="uid == user.id">
<div t-foreach="followed" t-as="question" class="mb16"> <div t-foreach="followed" t-as="question" class="mb16">
<t t-call="website_forum.display_post"/> <t t-call="website_forum.display_post"/>
</div> </div>
</div> </div>
<div class="tab-pane" id="votes"> <div class="tab-pane" id="votes" t-if="uid == user.id">
<t t-call="website_forum.user_votes"/> <t t-call="website_forum.user_votes"/>
</div> </div>
<div class="tab-pane" id="activity"> <div class="tab-pane" id="activity" t-if="uid == user.id">
<ul class="list-unstyled"> <ul class="list-unstyled">
<li t-foreach="activities" t-as="activity"> <li t-foreach="activities" t-as="activity">
<span t-field="activity.date" t-field-options='{"format": "short"}'/> <span t-field="activity.date" t-field-options='{"format": "short"}'/>