123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import json
- from bson import ObjectId, Decimal128
- from django.core.serializers.json import DjangoJSONEncoder
- from django.http import HttpResponse
- from apilib.monetary import RMB, VirtualCoin, Ratio, Percent
- from apilib.quantity import Quantity
- from apilib.systypes import StrEnum
- class DescriptiveJSONEncoder(DjangoJSONEncoder):
- def default(self, o):
- import datetime
- if isinstance(o, ObjectId):
- return str(o)
- elif isinstance(o, Decimal128):
- return str(o)
- elif isinstance(o, (RMB, VirtualCoin, Ratio, Percent)):
- return str(o)
- elif isinstance(o, Quantity):
- return str(o)
- elif isinstance(o, datetime.datetime):
- return o.strftime('%Y-%m-%d %H:%M:%S')
- return super(DescriptiveJSONEncoder, self).default(o)
- class CustomizedType(StrEnum):
- ObjectId = 'ObjectId'
- Decimal128 = 'Decimal128'
- RMB = 'RMB'
- VirtualCoin = 'VirtualCoin'
- Ratio = 'Ratio'
- Percent = 'Percent'
- Quantity = 'Quantity'
- datetime = 'datetime'
- class CustomizedTypeJSONEncoder(DjangoJSONEncoder):
- def default(self, o):
- import datetime
- if isinstance(o, ObjectId):
- return {'_spec_type': CustomizedType.ObjectId, 'val': str(o)}
- elif isinstance(o, Decimal128):
- return {'_spec_type': CustomizedType.Decimal128, 'val': str(o)}
- elif isinstance(o, RMB):
- return {'_spec_type': CustomizedType.RMB, 'val': str(o)}
- elif isinstance(o, VirtualCoin):
- return {'_spec_type': CustomizedType.VirtualCoin, 'val': str(o)}
- elif isinstance(o, Ratio):
- return {'_spec_type': CustomizedType.Ratio, 'val': str(o)}
- elif isinstance(o, Percent):
- return {'_spec_type': CustomizedType.Percent, 'val': str(o)}
- elif isinstance(o, Quantity):
- return {'_spec_type': CustomizedType.Quantity, 'val': str(o)}
- elif isinstance(o, datetime.datetime):
- return {'_spec_type': CustomizedType.datetime, 'val': o.strftime('%Y-%m-%d %H:%M:%S')}
- return super(CustomizedTypeJSONEncoder, self).default(o)
- def object_hook(obj):
- _spec_type = obj.get('_spec_type')
- if not _spec_type:
- return obj
- if _spec_type == CustomizedType.ObjectId:
- return ObjectId(obj.get('val'))
- if _spec_type == CustomizedType.RMB:
- return RMB(obj.get('val'))
- elif _spec_type == CustomizedType.VirtualCoin:
- return VirtualCoin(obj.get('val'))
- elif _spec_type == CustomizedType.Ratio:
- return Ratio(obj.get('val'))
- elif _spec_type == CustomizedType.Percent:
- return Percent(obj.get('val'))
- elif _spec_type == CustomizedType.Quantity:
- return Quantity(obj.get('val'))
- elif _spec_type == CustomizedType.datetime:
- import datetime
- return datetime.datetime.strptime(obj.get('val'), '%Y-%m-%d %H:%M:%S')
- elif _spec_type == CustomizedType.Decimal128:
- return Decimal128(str(obj.get('val')))
- raise Exception('Unknown {}'.format(_spec_type))
- def json_dumps(data, sort_keys = False, serialize_type = False):
- if not serialize_type:
- return json.dumps(data, sort_keys = sort_keys, cls = DescriptiveJSONEncoder)
- else:
- return json.dumps(data, sort_keys = sort_keys, cls = CustomizedTypeJSONEncoder)
- def json_loads(data):
- return json.loads(data, object_hook = object_hook)
- class JsonResponse(HttpResponse):
- def __init__(self, data, safe = True, ordered = False, **kwargs):
- if safe and not isinstance(data, dict):
- raise TypeError('In order to allow non-dict objects to be '
- 'serialized set the safe parameter to False')
- kwargs.setdefault('content_type', 'application/json')
- data = json_dumps(data, sort_keys = ordered)
- super(JsonResponse, self).__init__(content = data, **kwargs)
- def json(self):
- return json.loads(self.content)
|