|
1 """ |
|
2 Serialize data to/from JSON |
|
3 """ |
|
4 |
|
5 import datetime |
|
6 from django.utils import simplejson |
|
7 from django.core.serializers.python import Serializer as PythonSerializer |
|
8 from django.core.serializers.python import Deserializer as PythonDeserializer |
|
9 try: |
|
10 from cStringIO import StringIO |
|
11 except ImportError: |
|
12 from StringIO import StringIO |
|
13 try: |
|
14 import decimal |
|
15 except ImportError: |
|
16 from django.utils import _decimal as decimal # Python 2.3 fallback |
|
17 |
|
18 class Serializer(PythonSerializer): |
|
19 """ |
|
20 Convert a queryset to JSON. |
|
21 """ |
|
22 internal_use_only = False |
|
23 |
|
24 def end_serialization(self): |
|
25 self.options.pop('stream', None) |
|
26 self.options.pop('fields', None) |
|
27 simplejson.dump(self.objects, self.stream, cls=DjangoJSONEncoder, **self.options) |
|
28 |
|
29 def getvalue(self): |
|
30 if callable(getattr(self.stream, 'getvalue', None)): |
|
31 return self.stream.getvalue() |
|
32 |
|
33 def Deserializer(stream_or_string, **options): |
|
34 """ |
|
35 Deserialize a stream or string of JSON data. |
|
36 """ |
|
37 if isinstance(stream_or_string, basestring): |
|
38 stream = StringIO(stream_or_string) |
|
39 else: |
|
40 stream = stream_or_string |
|
41 for obj in PythonDeserializer(simplejson.load(stream)): |
|
42 yield obj |
|
43 |
|
44 class DjangoJSONEncoder(simplejson.JSONEncoder): |
|
45 """ |
|
46 JSONEncoder subclass that knows how to encode date/time and decimal types. |
|
47 """ |
|
48 |
|
49 DATE_FORMAT = "%Y-%m-%d" |
|
50 TIME_FORMAT = "%H:%M:%S" |
|
51 |
|
52 def default(self, o): |
|
53 if isinstance(o, datetime.datetime): |
|
54 return o.strftime("%s %s" % (self.DATE_FORMAT, self.TIME_FORMAT)) |
|
55 elif isinstance(o, datetime.date): |
|
56 return o.strftime(self.DATE_FORMAT) |
|
57 elif isinstance(o, datetime.time): |
|
58 return o.strftime(self.TIME_FORMAT) |
|
59 elif isinstance(o, decimal.Decimal): |
|
60 return str(o) |
|
61 else: |
|
62 return super(DjangoJSONEncoder, self).default(o) |
|
63 |
|
64 # Older, deprecated class name (for backwards compatibility purposes). |
|
65 DateTimeAwareJSONEncoder = DjangoJSONEncoder |
|
66 |