From 23fe797a9e521c504ec1c7b60415f317f6dfb68f Mon Sep 17 00:00:00 2001 From: Skia Date: Sun, 14 May 2017 04:36:04 +0200 Subject: [PATCH] Make less DB queries (particularly in the Forum) --- counter/models.py | 7 ++++++- forum/models.py | 13 +++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/counter/models.py b/counter/models.py index 15e34159..f45debd6 100644 --- a/counter/models.py +++ b/counter/models.py @@ -29,6 +29,7 @@ from django.conf import settings from django.core.urlresolvers import reverse from django.forms import ValidationError from django.contrib.sites.shortcuts import get_current_site +from django.utils.functional import cached_property from datetime import timedelta, date import random @@ -215,6 +216,10 @@ class Counter(models.Model): p.end = p.activity p.save() + @cached_property + def barmen_list(self): + return self.get_barmen_list() + def get_barmen_list(self): """ Returns the barman list as list of User @@ -246,7 +251,7 @@ class Counter(models.Model): p.save() # Update activity def is_open(self): - return len(self.get_barmen_list()) > 0 + return len(self.barmen_list) > 0 def is_inactive(self): """ diff --git a/forum/models.py b/forum/models.py index 0f2c3a8d..234b477d 100644 --- a/forum/models.py +++ b/forum/models.py @@ -136,10 +136,19 @@ class Forum(models.Model): def last_message(self): return self.get_last_message() + forum_list = {} # Class variable used for cache purpose def get_last_message(self): last_msg = None - for m in ForumMessage.objects.select_related('topic__forum', 'author').order_by('-id'): - forum = m.topic.forum + for m in ForumMessage.objects.select_related('topic__forum').order_by('-id'): + if m.topic.forum.id in Forum.forum_list.keys(): # The object is already in Python's memory, + # so there's no need to query it again + forum = Forum.forum_list[m.topic.forum.id] + else: # Query the forum object and store it in the class variable for further use. + # Keeping the same object allows the @cached_property to work properly. +# This trick divided by 4 the number of DB queries in the main forum page, and about the same on many other forum pages. +# This also divided by 4 the amount of CPU usage for thoses pages, according to Django Debug Toolbar. + forum = m.topic.forum + Forum.forum_list[forum.id] = forum if self in (forum.parent_list + [forum]) and not m.deleted: return m