json.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import decimal
  2. import json
  3. from django.core.serializers.json import DjangoJSONEncoder
  4. from utilities.datetime import datetime_from_timestamp
  5. __all__ = (
  6. 'ConfigJSONEncoder',
  7. 'CustomFieldJSONEncoder',
  8. 'JobLogDecoder',
  9. )
  10. class CustomFieldJSONEncoder(DjangoJSONEncoder):
  11. """
  12. Override Django's built-in JSON encoder to save decimal values as JSON numbers.
  13. """
  14. def default(self, o):
  15. if isinstance(o, decimal.Decimal):
  16. return float(o)
  17. return super().default(o)
  18. class ConfigJSONEncoder(DjangoJSONEncoder):
  19. """
  20. Override Django's built-in JSON encoder to serialize CustomValidator classes as strings.
  21. """
  22. def default(self, o):
  23. from extras.validators import CustomValidator
  24. if issubclass(type(o), CustomValidator):
  25. return type(o).__name__
  26. return super().default(o)
  27. class JobLogDecoder(json.JSONDecoder):
  28. """
  29. Deserialize JobLogEntry timestamps.
  30. """
  31. def __init__(self, *args, **kwargs):
  32. kwargs['object_hook'] = self._deserialize_entry
  33. super().__init__(*args, **kwargs)
  34. def _deserialize_entry(self, obj: dict) -> dict:
  35. if obj.get('timestamp'):
  36. # Deserialize a timestamp string to a native datetime object
  37. try:
  38. obj['timestamp'] = datetime_from_timestamp(obj['timestamp'])
  39. except ValueError:
  40. pass
  41. return obj