diff --git a/boards/models/post.py b/boards/models/post.py
--- a/boards/models/post.py
+++ b/boards/models/post.py
@@ -122,7 +122,7 @@ class PostManager(models.Manager):
for post in posts:
post.delete()
- @cached_result
+ @cached_result()
def get_posts_per_day(self) -> float:
"""
Gets average count of posts per day for the last 7 days
@@ -209,7 +209,7 @@ class Post(models.Model, Viewable):
return self.get_thread().get_opening_post_id() == self.id
- @cached_result
+ @cached_result()
def get_url(self):
"""
Gets full url to the post.
diff --git a/boards/models/thread.py b/boards/models/thread.py
--- a/boards/models/thread.py
+++ b/boards/models/thread.py
@@ -7,7 +7,7 @@ from django.db import models
from boards import settings
import boards
-from boards.utils import cached_result
+from boards.utils import cached_result, datetime_to_epoch
from boards.models.post import Post
from boards.models.tag import Tag
@@ -94,9 +94,14 @@ class Thread(models.Model):
self.bumpable = False
self.update_posts_time()
+ def _get_cache_key(self):
+ return [datetime_to_epoch(self.last_edit_time)]
+
+ @cached_result(key_method=_get_cache_key)
def get_reply_count(self) -> int:
return self.get_replies().count()
+ @cached_result(key_method=_get_cache_key)
def get_images_count(self) -> int:
return self.get_replies().annotate(images_count=Count(
'images')).aggregate(Sum('images_count'))['images_count__sum']
@@ -152,6 +157,7 @@ class Thread(models.Model):
return self.get_replies(view_fields_only).annotate(images_count=Count(
'images')).filter(images_count__gt=0)
+ # TODO Do we still need this?
def add_tag(self, tag: Tag):
"""
Connects thread to a tag and tag to a thread
@@ -171,7 +177,7 @@ class Thread(models.Model):
return opening_post
- @cached_result
+ @cached_result()
def get_opening_post_id(self) -> int:
"""
Gets ID of the first thread post.
@@ -217,4 +223,4 @@ class Thread(models.Model):
client.publish(channel_name, {
WS_NOTIFICATION_TYPE: WS_NOTIFICATION_TYPE_NEW_POST,
})
- client.send()
\ No newline at end of file
+ client.send()
diff --git a/boards/templates/boards/thread.html b/boards/templates/boards/thread.html
--- a/boards/templates/boards/thread.html
+++ b/boards/templates/boards/thread.html
@@ -1,7 +1,6 @@
{% extends "boards/base.html" %}
{% load i18n %}
-{% load cache %}
{% load static from staticfiles %}
{% load board %}
{% load tz %}
@@ -13,9 +12,6 @@
{% block metapanel %}
- {% get_current_language as LANGUAGE_CODE %}
- {% get_current_timezone as TIME_ZONE %}
-
{{ thread.get_reply_count }}{% if thread.has_post_limit %}/{{ thread.max_posts }}{% endif %} {% trans 'messages' %},
{{ thread.get_images_count }} {% trans 'images' %}.
{% trans 'Last update: ' %}
[RSS]
- {% endcache %}
{% endblock %}
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
+import functools
+
from django.core.cache import cache
from django.db.models import Model
@@ -11,9 +13,7 @@ from django.utils import timezone
from neboard import settings
-KEY_CAPTCHA_FAILS = 'key_captcha_fails'
-KEY_CAPTCHA_DELAY_TIME = 'key_captcha_delay_time'
-KEY_CAPTCHA_LAST_ACTIVITY = 'key_captcha_last_activity'
+CACHE_KEY_DELIMITER = '_'
def get_client_ip(request):
@@ -46,24 +46,31 @@ def get_websocket_token(user_id='', time
return token
-def cached_result(function):
+def cached_result(key_method=None):
"""
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)
+ def _cached_result(function):
+ def inner_func(obj, *args, **kwargs):
+ # TODO Include method arguments to the cache key
+ cache_key_params = [obj.__class__.__name__, function.__name__]
+ if isinstance(obj, Model):
+ cache_key_params.append(str(obj.id))
+
+ if key_method is not None:
+ cache_key_params += [str(arg) for arg in key_method(obj)]
+
+ cache_key = CACHE_KEY_DELIMITER.join(cache_key_params)
- persisted_result = cache.get(cache_key)
- if persisted_result:
- result = persisted_result
- else:
- result = function(obj, *args, **kwargs)
- cache.set(cache_key, result)
+ persisted_result = cache.get(cache_key)
+ if persisted_result is not None:
+ result = persisted_result
+ else:
+ result = function(obj, *args, **kwargs)
+ cache.set(cache_key, result)
- return result
+ return result
- return inner_func
+ return inner_func
+ return _cached_result