1from plain import preflight
2
3NOT_PROVIDED = object()
4
5
6class FieldCacheMixin:
7 """Provide an API for working with the model's fields value cache."""
8
9 def get_cache_name(self):
10 raise NotImplementedError
11
12 def get_cached_value(self, instance, default=NOT_PROVIDED):
13 cache_name = self.get_cache_name()
14 try:
15 return instance._state.fields_cache[cache_name]
16 except KeyError:
17 if default is NOT_PROVIDED:
18 raise
19 return default
20
21 def is_cached(self, instance):
22 return self.get_cache_name() in instance._state.fields_cache
23
24 def set_cached_value(self, instance, value):
25 instance._state.fields_cache[self.get_cache_name()] = value
26
27 def delete_cached_value(self, instance):
28 del instance._state.fields_cache[self.get_cache_name()]
29
30
31class CheckFieldDefaultMixin:
32 _default_hint = ("<valid default>", "<invalid default>")
33
34 def _check_default(self):
35 if (
36 self.has_default()
37 and self.default is not None
38 and not callable(self.default)
39 ):
40 return [
41 preflight.Warning(
42 "{} default should be a callable instead of an instance "
43 "so that it's not shared between all field instances.".format(
44 self.__class__.__name__
45 ),
46 hint=(
47 "Use a callable instead, e.g., use `{}` instead of "
48 "`{}`.".format(*self._default_hint)
49 ),
50 obj=self,
51 id="fields.E010",
52 )
53 ]
54 else:
55 return []
56
57 def check(self, **kwargs):
58 errors = super().check(**kwargs)
59 errors.extend(self._check_default())
60 return errors