# HG changeset patch # User neko259 # Date 2015-01-27 20:02:27 # Node ID 3848eb1fe2c24b98b740e66c65da941895dd91fb # Parent 61b1dba099725858cd3e240278a26c70cc173730 Started work on the method caching decorator (BB-57) diff --git a/boards/models/post.py b/boards/models/post.py --- a/boards/models/post.py +++ b/boards/models/post.py @@ -4,7 +4,6 @@ import logging import re from adjacent import Client -from django.core.cache import cache from django.core.urlresolvers import reverse from django.db import models, transaction from django.db.models import TextField @@ -16,7 +15,7 @@ from boards.mdx_neboard import bbcode_ex from boards.models import PostImage from boards.models.base import Viewable from boards.models.thread import Thread -from boards.utils import datetime_to_epoch +from boards.utils import datetime_to_epoch, cached_result WS_NOTIFICATION_TYPE_NEW_POST = 'new_post' @@ -26,9 +25,6 @@ WS_CHANNEL_THREAD = "thread:" APP_LABEL_BOARDS = 'boards' -CACHE_KEY_PPD = 'ppd' -CACHE_KEY_POST_URL = 'post_url' - POSTS_PER_DAY_RANGE = 7 BAN_REASON_AUTO = 'Auto' @@ -157,6 +153,7 @@ class PostManager(models.Manager): referenced_thread.last_edit_time = post.pub_time referenced_thread.save(update_fields=['last_edit_time']) + @cached_result def get_posts_per_day(self): """ Gets average count of posts per day for the last 7 days @@ -165,11 +162,6 @@ class PostManager(models.Manager): day_end = date.today() day_start = day_end - timedelta(POSTS_PER_DAY_RANGE) - cache_key = CACHE_KEY_PPD + str(day_end) - ppd = cache.get(cache_key) - if ppd: - return ppd - day_time_start = timezone.make_aware(datetime.combine( day_start, dtime()), timezone.get_current_timezone()) day_time_end = timezone.make_aware(datetime.combine( @@ -181,7 +173,6 @@ class PostManager(models.Manager): ppd = posts_per_period / POSTS_PER_DAY_RANGE - cache.set(cache_key, ppd) return ppd def _preparse_text(self, text): @@ -285,27 +276,22 @@ class Post(models.Model, Viewable): thread.last_edit_time = edit_time thread.save(update_fields=['last_edit_time']) + @cached_result def get_url(self, thread=None): """ Gets full url to the post. """ - cache_key = CACHE_KEY_POST_URL + str(self.id) - link = cache.get(cache_key) + if not thread: + thread = self.get_thread() - if not link: - if not thread: - thread = self.get_thread() + opening_id = thread.get_opening_post_id() - opening_id = thread.get_opening_post_id() - - if self.id != opening_id: - link = reverse('thread', kwargs={ - 'post_id': opening_id}) + '#' + str(self.id) - else: - link = reverse('thread', kwargs={'post_id': self.id}) - - cache.set(cache_key, link) + if self.id != opening_id: + link = reverse('thread', kwargs={ + 'post_id': opening_id}) + '#' + str(self.id) + else: + link = reverse('thread', kwargs={'post_id': self.id}) return link diff --git a/boards/models/thread.py b/boards/models/thread.py --- a/boards/models/thread.py +++ b/boards/models/thread.py @@ -1,9 +1,12 @@ import logging + from django.db.models import Count, Sum from django.utils import timezone -from django.core.cache import cache from django.db import models + from boards import settings +from boards.utils import cached_result + __author__ = 'neko259' @@ -11,9 +14,6 @@ from boards import settings logger = logging.getLogger(__name__) -CACHE_KEY_OPENING_POST = 'opening_post_id' - - class ThreadManager(models.Manager): def process_oldest_threads(self): """ @@ -153,18 +153,13 @@ class Thread(models.Model): return opening_post + @cached_result def get_opening_post_id(self): """ Gets ID of the first thread post. """ - cache_key = CACHE_KEY_OPENING_POST + str(self.id) - opening_post_id = cache.get(cache_key) - if not opening_post_id: - opening_post_id = self.get_opening_post(only_id=True).id - cache.set(cache_key, opening_post_id) - - return opening_post_id + return self.get_opening_post(only_id=True).id def __unicode__(self): return str(self.id) diff --git a/boards/utils.py b/boards/utils.py --- a/boards/utils.py +++ b/boards/utils.py @@ -3,6 +3,8 @@ This module contains helper functions an """ import time import hmac +from django.core.cache import cache +from django.db.models import Model from django.utils import timezone @@ -40,4 +42,27 @@ def get_websocket_token(user_id='', time sign.update(timestamp.encode()) token = sign.hexdigest() - return token \ No newline at end of file + return token + + +def cached_result(function): + """ + Caches method result in the Django's cache system, persisted by object name, + object name and model id if object is a Django model. + """ + def inner_func(obj, *args, **kwargs): + # TODO Include method arguments to the cache key + cache_key = obj.__class__.__name__ + '_' + function.__name__ + if isinstance(obj, Model): + cache_key += '_' + str(obj.id) + + persisted_result = cache.get(cache_key) + if persisted_result: + result = persisted_result + else: + result = function(obj, *args, **kwargs) + cache.set(cache_key, result) + + return result + + return inner_func \ No newline at end of file