##// END OF EJS Templates
Added ability to cache method result with additional arguments. Cache thread...
neko259 -
r1106:2a693c11 default
parent child Browse files
Show More
@@ -122,7 +122,7 b' class PostManager(models.Manager):'
122 for post in posts:
122 for post in posts:
123 post.delete()
123 post.delete()
124
124
125 @cached_result
125 @cached_result()
126 def get_posts_per_day(self) -> float:
126 def get_posts_per_day(self) -> float:
127 """
127 """
128 Gets average count of posts per day for the last 7 days
128 Gets average count of posts per day for the last 7 days
@@ -209,7 +209,7 b' class Post(models.Model, Viewable):'
209
209
210 return self.get_thread().get_opening_post_id() == self.id
210 return self.get_thread().get_opening_post_id() == self.id
211
211
212 @cached_result
212 @cached_result()
213 def get_url(self):
213 def get_url(self):
214 """
214 """
215 Gets full url to the post.
215 Gets full url to the post.
@@ -7,7 +7,7 b' from django.db import models'
7
7
8 from boards import settings
8 from boards import settings
9 import boards
9 import boards
10 from boards.utils import cached_result
10 from boards.utils import cached_result, datetime_to_epoch
11 from boards.models.post import Post
11 from boards.models.post import Post
12 from boards.models.tag import Tag
12 from boards.models.tag import Tag
13
13
@@ -94,9 +94,14 b' class Thread(models.Model):'
94 self.bumpable = False
94 self.bumpable = False
95 self.update_posts_time()
95 self.update_posts_time()
96
96
97 def _get_cache_key(self):
98 return [datetime_to_epoch(self.last_edit_time)]
99
100 @cached_result(key_method=_get_cache_key)
97 def get_reply_count(self) -> int:
101 def get_reply_count(self) -> int:
98 return self.get_replies().count()
102 return self.get_replies().count()
99
103
104 @cached_result(key_method=_get_cache_key)
100 def get_images_count(self) -> int:
105 def get_images_count(self) -> int:
101 return self.get_replies().annotate(images_count=Count(
106 return self.get_replies().annotate(images_count=Count(
102 'images')).aggregate(Sum('images_count'))['images_count__sum']
107 'images')).aggregate(Sum('images_count'))['images_count__sum']
@@ -152,6 +157,7 b' class Thread(models.Model):'
152 return self.get_replies(view_fields_only).annotate(images_count=Count(
157 return self.get_replies(view_fields_only).annotate(images_count=Count(
153 'images')).filter(images_count__gt=0)
158 'images')).filter(images_count__gt=0)
154
159
160 # TODO Do we still need this?
155 def add_tag(self, tag: Tag):
161 def add_tag(self, tag: Tag):
156 """
162 """
157 Connects thread to a tag and tag to a thread
163 Connects thread to a tag and tag to a thread
@@ -171,7 +177,7 b' class Thread(models.Model):'
171
177
172 return opening_post
178 return opening_post
173
179
174 @cached_result
180 @cached_result()
175 def get_opening_post_id(self) -> int:
181 def get_opening_post_id(self) -> int:
176 """
182 """
177 Gets ID of the first thread post.
183 Gets ID of the first thread post.
@@ -217,4 +223,4 b' class Thread(models.Model):'
217 client.publish(channel_name, {
223 client.publish(channel_name, {
218 WS_NOTIFICATION_TYPE: WS_NOTIFICATION_TYPE_NEW_POST,
224 WS_NOTIFICATION_TYPE: WS_NOTIFICATION_TYPE_NEW_POST,
219 })
225 })
220 client.send() No newline at end of file
226 client.send()
@@ -1,7 +1,6 b''
1 {% extends "boards/base.html" %}
1 {% extends "boards/base.html" %}
2
2
3 {% load i18n %}
3 {% load i18n %}
4 {% load cache %}
5 {% load static from staticfiles %}
4 {% load static from staticfiles %}
6 {% load board %}
5 {% load board %}
7 {% load tz %}
6 {% load tz %}
@@ -13,9 +12,6 b''
13
12
14 {% block metapanel %}
13 {% block metapanel %}
15
14
16 {% get_current_language as LANGUAGE_CODE %}
17 {% get_current_timezone as TIME_ZONE %}
18
19 <span class="metapanel"
15 <span class="metapanel"
20 data-last-update="{{ last_update }}"
16 data-last-update="{{ last_update }}"
21 data-ws-token-time="{{ ws_token_time }}"
17 data-ws-token-time="{{ ws_token_time }}"
@@ -27,12 +23,10 b''
27 {% block thread_meta_panel %}
23 {% block thread_meta_panel %}
28 {% endblock %}
24 {% endblock %}
29
25
30 {% cache 600 thread_meta thread.last_edit_time moderator LANGUAGE_CODE TIME_ZONE %}
31 <span id="reply-count">{{ thread.get_reply_count }}</span>{% if thread.has_post_limit %}/{{ thread.max_posts }}{% endif %} {% trans 'messages' %},
26 <span id="reply-count">{{ thread.get_reply_count }}</span>{% if thread.has_post_limit %}/{{ thread.max_posts }}{% endif %} {% trans 'messages' %},
32 <span id="image-count">{{ thread.get_images_count }}</span> {% trans 'images' %}.
27 <span id="image-count">{{ thread.get_images_count }}</span> {% trans 'images' %}.
33 {% trans 'Last update: ' %}<span id="last-update"><time datetime="{{ thread.last_edit_time|date:'c' }}">{{ thread.last_edit_time }}</time></span>
28 {% trans 'Last update: ' %}<span id="last-update"><time datetime="{{ thread.last_edit_time|date:'c' }}">{{ thread.last_edit_time }}</time></span>
34 [<a href="rss/">RSS</a>]
29 [<a href="rss/">RSS</a>]
35 {% endcache %}
36 </span>
30 </span>
37
31
38 {% endblock %}
32 {% endblock %}
@@ -3,6 +3,8 b' This module contains helper functions an'
3 """
3 """
4 import time
4 import time
5 import hmac
5 import hmac
6 import functools
7
6 from django.core.cache import cache
8 from django.core.cache import cache
7 from django.db.models import Model
9 from django.db.models import Model
8
10
@@ -11,9 +13,7 b' from django.utils import timezone'
11 from neboard import settings
13 from neboard import settings
12
14
13
15
14 KEY_CAPTCHA_FAILS = 'key_captcha_fails'
16 CACHE_KEY_DELIMITER = '_'
15 KEY_CAPTCHA_DELAY_TIME = 'key_captcha_delay_time'
16 KEY_CAPTCHA_LAST_ACTIVITY = 'key_captcha_last_activity'
17
17
18
18
19 def get_client_ip(request):
19 def get_client_ip(request):
@@ -46,24 +46,31 b" def get_websocket_token(user_id='', time"
46 return token
46 return token
47
47
48
48
49 def cached_result(function):
49 def cached_result(key_method=None):
50 """
50 """
51 Caches method result in the Django's cache system, persisted by object name,
51 Caches method result in the Django's cache system, persisted by object name,
52 object name and model id if object is a Django model.
52 object name and model id if object is a Django model.
53 """
53 """
54 def inner_func(obj, *args, **kwargs):
54 def _cached_result(function):
55 # TODO Include method arguments to the cache key
55 def inner_func(obj, *args, **kwargs):
56 cache_key = obj.__class__.__name__ + '_' + function.__name__
56 # TODO Include method arguments to the cache key
57 if isinstance(obj, Model):
57 cache_key_params = [obj.__class__.__name__, function.__name__]
58 cache_key += '_' + str(obj.id)
58 if isinstance(obj, Model):
59 cache_key_params.append(str(obj.id))
60
61 if key_method is not None:
62 cache_key_params += [str(arg) for arg in key_method(obj)]
63
64 cache_key = CACHE_KEY_DELIMITER.join(cache_key_params)
59
65
60 persisted_result = cache.get(cache_key)
66 persisted_result = cache.get(cache_key)
61 if persisted_result:
67 if persisted_result is not None:
62 result = persisted_result
68 result = persisted_result
63 else:
69 else:
64 result = function(obj, *args, **kwargs)
70 result = function(obj, *args, **kwargs)
65 cache.set(cache_key, result)
71 cache.set(cache_key, result)
66
72
67 return result
73 return result
68
74
69 return inner_func
75 return inner_func
76 return _cached_result
General Comments 0
You need to be logged in to leave comments. Login now