Coverage for utilities/json.py: 36%
27 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
1import decimal
2import json
4from django.core.serializers.json import DjangoJSONEncoder
6from utilities.datetime import datetime_from_timestamp
8__all__ = (
9 'ConfigJSONEncoder',
10 'CustomFieldJSONEncoder',
11 'JobLogDecoder',
12)
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)
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
32 if issubclass(type(o), CustomValidator):
33 return type(o).__name__
35 return super().default(o)
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)
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