utils_json.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import json
  4. from bson import ObjectId, Decimal128
  5. from django.core.serializers.json import DjangoJSONEncoder
  6. from django.http import HttpResponse
  7. from apilib.monetary import RMB, VirtualCoin, Ratio, Percent
  8. from apilib.quantity import Quantity
  9. from apilib.systypes import StrEnum
  10. class DescriptiveJSONEncoder(DjangoJSONEncoder):
  11. def default(self, o):
  12. import datetime
  13. if isinstance(o, ObjectId):
  14. return str(o)
  15. elif isinstance(o, Decimal128):
  16. return str(o)
  17. elif isinstance(o, (RMB, VirtualCoin, Ratio, Percent)):
  18. return str(o)
  19. elif isinstance(o, Quantity):
  20. return str(o)
  21. elif isinstance(o, datetime.datetime):
  22. return o.strftime('%Y-%m-%d %H:%M:%S')
  23. return super(DescriptiveJSONEncoder, self).default(o)
  24. class CustomizedType(StrEnum):
  25. ObjectId = 'ObjectId'
  26. Decimal128 = 'Decimal128'
  27. RMB = 'RMB'
  28. VirtualCoin = 'VirtualCoin'
  29. Ratio = 'Ratio'
  30. Percent = 'Percent'
  31. Quantity = 'Quantity'
  32. datetime = 'datetime'
  33. class CustomizedTypeJSONEncoder(DjangoJSONEncoder):
  34. def default(self, o):
  35. import datetime
  36. if isinstance(o, ObjectId):
  37. return {'_spec_type': CustomizedType.ObjectId, 'val': str(o)}
  38. elif isinstance(o, Decimal128):
  39. return {'_spec_type': CustomizedType.Decimal128, 'val': str(o)}
  40. elif isinstance(o, RMB):
  41. return {'_spec_type': CustomizedType.RMB, 'val': str(o)}
  42. elif isinstance(o, VirtualCoin):
  43. return {'_spec_type': CustomizedType.VirtualCoin, 'val': str(o)}
  44. elif isinstance(o, Ratio):
  45. return {'_spec_type': CustomizedType.Ratio, 'val': str(o)}
  46. elif isinstance(o, Percent):
  47. return {'_spec_type': CustomizedType.Percent, 'val': str(o)}
  48. elif isinstance(o, Quantity):
  49. return {'_spec_type': CustomizedType.Quantity, 'val': str(o)}
  50. elif isinstance(o, datetime.datetime):
  51. return {'_spec_type': CustomizedType.datetime, 'val': o.strftime('%Y-%m-%d %H:%M:%S')}
  52. return super(CustomizedTypeJSONEncoder, self).default(o)
  53. def object_hook(obj):
  54. _spec_type = obj.get('_spec_type')
  55. if not _spec_type:
  56. return obj
  57. if _spec_type == CustomizedType.ObjectId:
  58. return ObjectId(obj.get('val'))
  59. if _spec_type == CustomizedType.RMB:
  60. return RMB(obj.get('val'))
  61. elif _spec_type == CustomizedType.VirtualCoin:
  62. return VirtualCoin(obj.get('val'))
  63. elif _spec_type == CustomizedType.Ratio:
  64. return Ratio(obj.get('val'))
  65. elif _spec_type == CustomizedType.Percent:
  66. return Percent(obj.get('val'))
  67. elif _spec_type == CustomizedType.Quantity:
  68. return Quantity(obj.get('val'))
  69. elif _spec_type == CustomizedType.datetime:
  70. import datetime
  71. return datetime.datetime.strptime(obj.get('val'), '%Y-%m-%d %H:%M:%S')
  72. elif _spec_type == CustomizedType.Decimal128:
  73. return Decimal128(str(obj.get('val')))
  74. raise Exception('Unknown {}'.format(_spec_type))
  75. def json_dumps(data, sort_keys = False, serialize_type = False):
  76. if not serialize_type:
  77. return json.dumps(data, sort_keys = sort_keys, cls = DescriptiveJSONEncoder)
  78. else:
  79. return json.dumps(data, sort_keys = sort_keys, cls = CustomizedTypeJSONEncoder)
  80. def json_loads(data):
  81. return json.loads(data, object_hook = object_hook)
  82. class JsonResponse(HttpResponse):
  83. def __init__(self, data, safe = True, ordered = False, **kwargs):
  84. if safe and not isinstance(data, dict):
  85. raise TypeError('In order to allow non-dict objects to be '
  86. 'serialized set the safe parameter to False')
  87. kwargs.setdefault('content_type', 'application/json')
  88. data = json_dumps(data, sort_keys = ordered)
  89. super(JsonResponse, self).__init__(content = data, **kwargs)
  90. def json(self):
  91. return json.loads(self.content)