-
Notifications
You must be signed in to change notification settings - Fork 15
/
managers.py
80 lines (65 loc) · 2.73 KB
/
managers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# coding: utf-8
import re
import django
from django.core.cache import cache
from django.db.models import Manager
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
VARIANTS_DICT_CACHE_KEY = 'terms__variants_dict'
REPLACE_DICT_CACHE_KEY = 'terms__replace_dict'
REPLACE_REGEXP_CACHE_KEY = 'terms__replace_regexp'
CACHE_KEYS = (VARIANTS_DICT_CACHE_KEY, REPLACE_DICT_CACHE_KEY,
REPLACE_REGEXP_CACHE_KEY)
class TermManager(Manager):
def _get_variants_dict(self, qs):
variants_dict = {}
for term in qs:
name_variants = term.name_variants()
for variant in name_variants:
variants_dict[variant.lower()] = name_variants
return variants_dict
def _get_replace_dict(self, qs):
replace_dict = {}
template = 'terms/term_replace.html'
for term in qs:
url = term.get_absolute_url()
name_variants = term.name_variants()
context = {'url': url.replace('%', '%%'),
'url_is_external': bool(term.url),
'tooltip_span': _('Open in new window'),
'definition': term.definition}
case_sensitive = term.case_sensitive
for name_variant in name_variants:
replace_dict[name_variant.lower()] = \
render_to_string(template, context), case_sensitive
return replace_dict
def _caches_dicts(self):
"""
Caches variants_dict and replace_dict in a single database hit.
"""
qs = (self.get_query_set() if django.VERSION < (1, 6)
else self.get_queryset())
variants_dict = self._get_variants_dict(qs)
cache.set(VARIANTS_DICT_CACHE_KEY, variants_dict)
replace_dict = self._get_replace_dict(qs)
cache.set(REPLACE_DICT_CACHE_KEY, replace_dict)
return variants_dict, replace_dict
def variants_dict(self):
variants_dict = cache.get(VARIANTS_DICT_CACHE_KEY)
if variants_dict is None:
return self._caches_dicts()[0]
return variants_dict
def replace_dict(self):
replace_dict = cache.get(REPLACE_DICT_CACHE_KEY)
if replace_dict is None:
return self._caches_dicts()[1]
return replace_dict
def replace_regexp(self):
r = cache.get(REPLACE_REGEXP_CACHE_KEY)
if r is None:
terms = sorted(self.replace_dict().keys(), key=len, reverse=True)
r = re.compile('(?P<before>\A|\W)(?P<name>%s)(?=\W|\Z)'
% '|'.join(map(re.escape, terms)),
flags=re.IGNORECASE | re.UNICODE)
cache.set(REPLACE_REGEXP_CACHE_KEY, r)
return r