Coverage for jutil/cache.py: 0%

# Coverage for jutil/cache.py : 0%

## 34 statements 0 run 34 missing 0 excluded 0 partial

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

1 import logging

2 from typing import Optional, TYPE_CHECKING, Any, Sequence

3

4 logger = logging.getLogger(__name__)

5

6

7 class 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] = []

16

17 if TYPE_CHECKING:

18 pk: Any = None

19

20 def save(self, force_insert=False, force_update=False, using=None,

21 update_fields=None):

22 pass

23

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

46

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)

54

55

56 def 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()