Coverage for jutil/cache.py : 0%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import logging
2from typing import Optional, TYPE_CHECKING, Any, Sequence
4logger = logging.getLogger(__name__)
7class CachedFieldsMixin:
8 """
9 Cached fields mixin. Usage:
10 1) List cached field names in cached_fields list
11 2) Implement get_xxx functions where xxx is cached field name
12 3) Call update_cached_fields() to refresh
13 4) Optionally call update_cached_fields_pre_save() on pre_save signal for objects (to automatically refresh on save)
14 """
15 cached_fields: Sequence[str] = []
17 if TYPE_CHECKING:
18 pk: Any = None
20 def save(self, force_insert=False, force_update=False, using=None,
21 update_fields=None):
22 pass
24 def update_cached_fields(self, commit: bool = True, exceptions: bool = True,
25 updated_fields: Optional[Sequence[str]] = None):
26 """
27 Updates cached fields using get_xxx calls for each cached field (in cached_fields list).
28 :param commit: Save update fields to DB
29 :param exceptions: Raise exceptions or not
30 :param updated_fields: List of cached fields to update. Pass None for all cached fields.
31 """
32 try:
33 fields = updated_fields or self.cached_fields
34 for k in fields:
35 f = 'get_' + k
36 if not hasattr(self, f):
37 raise Exception('Field {k} marked as cached in {obj} but function get_{k}() does not exist'.format(k=k, obj=self))
38 v = self.__getattribute__(f)()
39 setattr(self, k, v)
40 if commit:
41 self.save(update_fields=fields) # pytype: disable=attribute-error
42 except Exception as e:
43 logger.error('%s.update_cached_fields: %s', self.__class__, e)
44 if exceptions:
45 raise e
47 def update_cached_fields_pre_save(self, update_fields: Optional[Sequence[str]]):
48 """
49 Call on pre_save signal for objects (to automatically refresh on save).
50 :param update_fields: list of fields to update
51 """
52 if hasattr(self, 'pk') and self.pk and update_fields is None:
53 self.update_cached_fields(commit=False, exceptions=False)
56def update_cached_fields(*args):
57 """
58 Calls update_cached_fields() for each object passed in as argument.
59 Supports also iterable objects by checking __iter__ attribute.
60 :param args: List of objects
61 :return: None
62 """
63 for a in args:
64 if a is not None:
65 if hasattr(a, '__iter__'):
66 for e in a:
67 e.update_cached_fields()
68 else:
69 a.update_cached_fields()