web/lib/django/core/serializers/base.py
changeset 0 0d40e90630ef
child 29 cc9b7e14412b
equal deleted inserted replaced
-1:000000000000 0:0d40e90630ef
       
     1 """
       
     2 Module for abstract serializer/unserializer base classes.
       
     3 """
       
     4 
       
     5 from StringIO import StringIO
       
     6 
       
     7 from django.db import models
       
     8 from django.utils.encoding import smart_str, smart_unicode
       
     9 from django.utils import datetime_safe
       
    10 
       
    11 class SerializationError(Exception):
       
    12     """Something bad happened during serialization."""
       
    13     pass
       
    14 
       
    15 class DeserializationError(Exception):
       
    16     """Something bad happened during deserialization."""
       
    17     pass
       
    18 
       
    19 class Serializer(object):
       
    20     """
       
    21     Abstract serializer base class.
       
    22     """
       
    23 
       
    24     # Indicates if the implemented serializer is only available for
       
    25     # internal Django use.
       
    26     internal_use_only = False
       
    27 
       
    28     def serialize(self, queryset, **options):
       
    29         """
       
    30         Serialize a queryset.
       
    31         """
       
    32         self.options = options
       
    33 
       
    34         self.stream = options.get("stream", StringIO())
       
    35         self.selected_fields = options.get("fields")
       
    36 
       
    37         self.start_serialization()
       
    38         for obj in queryset:
       
    39             self.start_object(obj)
       
    40             for field in obj._meta.local_fields:
       
    41                 if field.serialize:
       
    42                     if field.rel is None:
       
    43                         if self.selected_fields is None or field.attname in self.selected_fields:
       
    44                             self.handle_field(obj, field)
       
    45                     else:
       
    46                         if self.selected_fields is None or field.attname[:-3] in self.selected_fields:
       
    47                             self.handle_fk_field(obj, field)
       
    48             for field in obj._meta.many_to_many:
       
    49                 if field.serialize:
       
    50                     if self.selected_fields is None or field.attname in self.selected_fields:
       
    51                         self.handle_m2m_field(obj, field)
       
    52             self.end_object(obj)
       
    53         self.end_serialization()
       
    54         return self.getvalue()
       
    55 
       
    56     def get_string_value(self, obj, field):
       
    57         """
       
    58         Convert a field's value to a string.
       
    59         """
       
    60         return smart_unicode(field.value_to_string(obj))
       
    61 
       
    62     def start_serialization(self):
       
    63         """
       
    64         Called when serializing of the queryset starts.
       
    65         """
       
    66         raise NotImplementedError
       
    67 
       
    68     def end_serialization(self):
       
    69         """
       
    70         Called when serializing of the queryset ends.
       
    71         """
       
    72         pass
       
    73 
       
    74     def start_object(self, obj):
       
    75         """
       
    76         Called when serializing of an object starts.
       
    77         """
       
    78         raise NotImplementedError
       
    79 
       
    80     def end_object(self, obj):
       
    81         """
       
    82         Called when serializing of an object ends.
       
    83         """
       
    84         pass
       
    85 
       
    86     def handle_field(self, obj, field):
       
    87         """
       
    88         Called to handle each individual (non-relational) field on an object.
       
    89         """
       
    90         raise NotImplementedError
       
    91 
       
    92     def handle_fk_field(self, obj, field):
       
    93         """
       
    94         Called to handle a ForeignKey field.
       
    95         """
       
    96         raise NotImplementedError
       
    97 
       
    98     def handle_m2m_field(self, obj, field):
       
    99         """
       
   100         Called to handle a ManyToManyField.
       
   101         """
       
   102         raise NotImplementedError
       
   103 
       
   104     def getvalue(self):
       
   105         """
       
   106         Return the fully serialized queryset (or None if the output stream is
       
   107         not seekable).
       
   108         """
       
   109         if callable(getattr(self.stream, 'getvalue', None)):
       
   110             return self.stream.getvalue()
       
   111 
       
   112 class Deserializer(object):
       
   113     """
       
   114     Abstract base deserializer class.
       
   115     """
       
   116 
       
   117     def __init__(self, stream_or_string, **options):
       
   118         """
       
   119         Init this serializer given a stream or a string
       
   120         """
       
   121         self.options = options
       
   122         if isinstance(stream_or_string, basestring):
       
   123             self.stream = StringIO(stream_or_string)
       
   124         else:
       
   125             self.stream = stream_or_string
       
   126         # hack to make sure that the models have all been loaded before
       
   127         # deserialization starts (otherwise subclass calls to get_model()
       
   128         # and friends might fail...)
       
   129         models.get_apps()
       
   130 
       
   131     def __iter__(self):
       
   132         return self
       
   133 
       
   134     def next(self):
       
   135         """Iteration iterface -- return the next item in the stream"""
       
   136         raise NotImplementedError
       
   137 
       
   138 class DeserializedObject(object):
       
   139     """
       
   140     A deserialized model.
       
   141 
       
   142     Basically a container for holding the pre-saved deserialized data along
       
   143     with the many-to-many data saved with the object.
       
   144 
       
   145     Call ``save()`` to save the object (with the many-to-many data) to the
       
   146     database; call ``save(save_m2m=False)`` to save just the object fields
       
   147     (and not touch the many-to-many stuff.)
       
   148     """
       
   149 
       
   150     def __init__(self, obj, m2m_data=None):
       
   151         self.object = obj
       
   152         self.m2m_data = m2m_data
       
   153 
       
   154     def __repr__(self):
       
   155         return "<DeserializedObject: %s>" % smart_str(self.object)
       
   156 
       
   157     def save(self, save_m2m=True):
       
   158         # Call save on the Model baseclass directly. This bypasses any
       
   159         # model-defined save. The save is also forced to be raw.
       
   160         # This ensures that the data that is deserialized is literally
       
   161         # what came from the file, not post-processed by pre_save/save
       
   162         # methods.
       
   163         models.Model.save_base(self.object, raw=True)
       
   164         if self.m2m_data and save_m2m:
       
   165             for accessor_name, object_list in self.m2m_data.items():
       
   166                 setattr(self.object, accessor_name, object_list)
       
   167 
       
   168         # prevent a second (possibly accidental) call to save() from saving
       
   169         # the m2m data twice.
       
   170         self.m2m_data = None