root / env / lib / python2.7 / site-packages / django / core / serializers / json.py @ 1a305335
History | View | Annotate | Download (2.47 KB)
1 |
"""
|
---|---|
2 |
Serialize data to/from JSON
|
3 |
"""
|
4 |
|
5 |
import datetime |
6 |
import decimal |
7 |
from StringIO import StringIO |
8 |
|
9 |
from django.core.serializers.base import DeserializationError |
10 |
from django.core.serializers.python import Serializer as PythonSerializer |
11 |
from django.core.serializers.python import Deserializer as PythonDeserializer |
12 |
from django.utils import simplejson |
13 |
from django.utils.timezone import is_aware |
14 |
|
15 |
class Serializer(PythonSerializer): |
16 |
"""
|
17 |
Convert a queryset to JSON.
|
18 |
"""
|
19 |
internal_use_only = False
|
20 |
|
21 |
def end_serialization(self): |
22 |
if simplejson.__version__.split('.') >= ['2', '1', '3']: |
23 |
# Use JS strings to represent Python Decimal instances (ticket #16850)
|
24 |
self.options.update({'use_decimal': False}) |
25 |
simplejson.dump(self.objects, self.stream, cls=DjangoJSONEncoder, **self.options) |
26 |
|
27 |
def getvalue(self): |
28 |
if callable(getattr(self.stream, 'getvalue', None)): |
29 |
return self.stream.getvalue() |
30 |
|
31 |
|
32 |
def Deserializer(stream_or_string, **options): |
33 |
"""
|
34 |
Deserialize a stream or string of JSON data.
|
35 |
"""
|
36 |
if isinstance(stream_or_string, basestring): |
37 |
stream = StringIO(stream_or_string) |
38 |
else:
|
39 |
stream = stream_or_string |
40 |
try:
|
41 |
for obj in PythonDeserializer(simplejson.load(stream), **options): |
42 |
yield obj
|
43 |
except GeneratorExit: |
44 |
raise
|
45 |
except Exception, e: |
46 |
# Map to deserializer error
|
47 |
raise DeserializationError(e)
|
48 |
|
49 |
|
50 |
class DjangoJSONEncoder(simplejson.JSONEncoder): |
51 |
"""
|
52 |
JSONEncoder subclass that knows how to encode date/time and decimal types.
|
53 |
"""
|
54 |
def default(self, o): |
55 |
# See "Date Time String Format" in the ECMA-262 specification.
|
56 |
if isinstance(o, datetime.datetime): |
57 |
r = o.isoformat() |
58 |
if o.microsecond:
|
59 |
r = r[:23] + r[26:] |
60 |
if r.endswith('+00:00'): |
61 |
r = r[:-6] + 'Z' |
62 |
return r
|
63 |
elif isinstance(o, datetime.date): |
64 |
return o.isoformat()
|
65 |
elif isinstance(o, datetime.time): |
66 |
if is_aware(o):
|
67 |
raise ValueError("JSON can't represent timezone-aware times.") |
68 |
r = o.isoformat() |
69 |
if o.microsecond:
|
70 |
r = r[:12]
|
71 |
return r
|
72 |
elif isinstance(o, decimal.Decimal): |
73 |
return str(o) |
74 |
else:
|
75 |
return super(DjangoJSONEncoder, self).default(o) |
76 |
|
77 |
# Older, deprecated class name (for backwards compatibility purposes).
|
78 |
DateTimeAwareJSONEncoder = DjangoJSONEncoder |
79 |
|