Project

General

Profile

Statistics
| Branch: | Revision:

root / env / lib / python2.7 / site-packages / django / core / serializers / pyyaml.py @ 1a305335

History | View | Annotate | Download (2.12 KB)

1 1a305335 officers
"""
2
YAML serializer.
3

4
Requires PyYaml (http://pyyaml.org/), but that's checked for in __init__.
5
"""
6
7
from StringIO import StringIO
8
import decimal
9
import yaml
10
11
from django.db import models
12
from django.core.serializers.base import DeserializationError
13
from django.core.serializers.python import Serializer as PythonSerializer
14
from django.core.serializers.python import Deserializer as PythonDeserializer
15
16
class DjangoSafeDumper(yaml.SafeDumper):
17
    def represent_decimal(self, data):
18
        return self.represent_scalar('tag:yaml.org,2002:str', str(data))
19
20
DjangoSafeDumper.add_representer(decimal.Decimal, DjangoSafeDumper.represent_decimal)
21
22
class Serializer(PythonSerializer):
23
    """
24
    Convert a queryset to YAML.
25
    """
26
27
    internal_use_only = False
28
29
    def handle_field(self, obj, field):
30
        # A nasty special case: base YAML doesn't support serialization of time
31
        # types (as opposed to dates or datetimes, which it does support). Since
32
        # we want to use the "safe" serializer for better interoperability, we
33
        # need to do something with those pesky times. Converting 'em to strings
34
        # isn't perfect, but it's better than a "!!python/time" type which would
35
        # halt deserialization under any other language.
36
        if isinstance(field, models.TimeField) and getattr(obj, field.name) is not None:
37
            self._current[field.name] = str(getattr(obj, field.name))
38
        else:
39
            super(Serializer, self).handle_field(obj, field)
40
41
    def end_serialization(self):
42
        yaml.dump(self.objects, self.stream, Dumper=DjangoSafeDumper, **self.options)
43
44
    def getvalue(self):
45
        return self.stream.getvalue()
46
47
def Deserializer(stream_or_string, **options):
48
    """
49
    Deserialize a stream or string of YAML data.
50
    """
51
    if isinstance(stream_or_string, basestring):
52
        stream = StringIO(stream_or_string)
53
    else:
54
        stream = stream_or_string
55
    try:
56
        for obj in PythonDeserializer(yaml.safe_load(stream), **options):
57
            yield obj
58
    except GeneratorExit:
59
        raise
60
    except Exception, e:
61
        # Map to deserializer error
62
        raise DeserializationError(e)