Coverage for utilities/json.py: 36%

27 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 18:35 +0000

1import decimal 

2import json 

3 

4from django.core.serializers.json import DjangoJSONEncoder 

5 

6from utilities.datetime import datetime_from_timestamp 

7 

8__all__ = ( 

9 'ConfigJSONEncoder', 

10 'CustomFieldJSONEncoder', 

11 'JobLogDecoder', 

12) 

13 

14 

15class CustomFieldJSONEncoder(DjangoJSONEncoder): 

16 """ 

17 Override Django's built-in JSON encoder to save decimal values as JSON numbers. 

18 """ 

19 def default(self, o): 

20 if isinstance(o, decimal.Decimal): 

21 return float(o) 

22 return super().default(o) 

23 

24 

25class ConfigJSONEncoder(DjangoJSONEncoder): 

26 """ 

27 Override Django's built-in JSON encoder to serialize CustomValidator classes as strings. 

28 """ 

29 def default(self, o): 

30 from extras.validators import CustomValidator 

31 

32 if issubclass(type(o), CustomValidator): 

33 return type(o).__name__ 

34 

35 return super().default(o) 

36 

37 

38class JobLogDecoder(json.JSONDecoder): 

39 """ 

40 Deserialize JobLogEntry timestamps. 

41 """ 

42 def __init__(self, *args, **kwargs): 

43 kwargs['object_hook'] = self._deserialize_entry 

44 super().__init__(*args, **kwargs) 

45 

46 def _deserialize_entry(self, obj: dict) -> dict: 

47 if obj.get('timestamp'): 

48 # Deserialize a timestamp string to a native datetime object 

49 try: 

50 obj['timestamp'] = datetime_from_timestamp(obj['timestamp']) 

51 except ValueError: 

52 pass 

53 return obj