[FIX] website_forum: avoid search in a loop for last post

Computation of the last post shouldn't be done with a
db request for each forum but can be batched.

Technical note:
As it is likely that `post_ids` is not yet fetched when we're
accessing `last_post_id` we chose not to early return if no
forum in `self` included posts already.

Version choice:
We chose this version to merge this as it is the one where
forum was taken over, and _read_group refactored.

A test for this computation is also added.

Task-3685002

closes odoo/odoo#150444

X-original-commit: ba3af942deee4818edb32d08b9bb07652253a029
Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
Signed-off-by: Florian Charlier (flch) <flch@odoo.com>
This commit is contained in:
Florian Charlier
2024-01-23 05:56:21 +00:00
parent e5d7c4fef2
commit c3b7eac631
2 changed files with 24 additions and 4 deletions
+6 -4
View File
@@ -198,11 +198,13 @@ class Forum(models.Model):
@api.depends('post_ids')
def _compute_last_post_id(self):
last_forums_posts = self.env['forum.post']._read_group(
[('forum_id', 'in', self.ids), ('parent_id', '=', False), ('state', '=', 'active')],
groupby=['forum_id'], aggregates=['id:max'],
)
forum_to_last_post_id = {forum.id: last_post_id for forum, last_post_id in last_forums_posts}
for forum in self:
forum.last_post_id = forum.post_ids.search(
[('forum_id', '=', forum.id), ('parent_id', '=', False), ('state', '=', 'active')],
order='create_date desc', limit=1,
)
forum.last_post_id = forum_to_last_post_id.get(forum.id, False)
@api.depends('post_ids.state', 'post_ids.views', 'post_ids.child_count', 'post_ids.favourite_count')
def _compute_forum_statistics(self):
@@ -59,6 +59,24 @@ class TestForumInternals(TestForumCommon):
self.assertEqual(website_2.forum_count, 6,
'6 global forums')
def test_website_forum_last_post_id(self):
"""Check that each forum's last post is computed correctly and efficiently."""
test_forums = self.base_forum | self.forum
new_posts = self.env["forum.post"].create([{
'name': f'New Post {forum_post_idx}',
'forum_id': forum.id,
} for forum_post_idx, forum in enumerate(test_forums)])
with self.assertQueryCount(1):
self.assertEqual(test_forums.last_post_id.ids, new_posts.ids)
another_post = self.env["forum.post"].create([{
'name': 'Another New Post',
'forum_id': self.base_forum.id,
}])
with self.assertQueryCount(1):
self.assertEqual(test_forums.last_post_id.ids, (another_post | new_posts[1]).ids)
@tagged('forum_internals')
class TestPostInternals(TestForumCommon):