Fixed #2611 -- Fixed XML serializer to handle null datetime fields. Thanks for reporting, csdurfee@gmail.com

git-svn-id: http://code.djangoproject.com/svn/django/trunk@3687 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2006-08-31 04:11:46 +00:00
parent 452847a659
commit 22303d6c7d
1 changed files with 29 additions and 25 deletions

View File

@ -11,7 +11,7 @@ from django.db import models
class SerializationError(Exception): class SerializationError(Exception):
"""Something bad happened during serialization.""" """Something bad happened during serialization."""
pass pass
class DeserializationError(Exception): class DeserializationError(Exception):
"""Something bad happened during deserialization.""" """Something bad happened during deserialization."""
pass pass
@ -20,15 +20,15 @@ class Serializer(object):
""" """
Abstract serializer base class. Abstract serializer base class.
""" """
def serialize(self, queryset, **options): def serialize(self, queryset, **options):
""" """
Serialize a queryset. Serialize a queryset.
""" """
self.options = options self.options = options
self.stream = options.get("stream", StringIO()) self.stream = options.get("stream", StringIO())
self.start_serialization() self.start_serialization()
for obj in queryset: for obj in queryset:
self.start_object(obj) self.start_object(obj)
@ -44,61 +44,65 @@ class Serializer(object):
self.end_object(obj) self.end_object(obj)
self.end_serialization() self.end_serialization()
return self.getvalue() return self.getvalue()
def get_string_value(self, obj, field): def get_string_value(self, obj, field):
""" """
Convert a field's value to a string. Convert a field's value to a string.
""" """
if isinstance(field, models.DateTimeField): if isinstance(field, models.DateTimeField):
value = getattr(obj, field.name).strftime("%Y-%m-%d %H:%M:%S") value = getattr(obj, field.name)
if value is None:
value = ''
else:
value = value.strftime("%Y-%m-%d %H:%M:%S")
elif isinstance(field, models.FileField): elif isinstance(field, models.FileField):
value = getattr(obj, "get_%s_url" % field.name, lambda: None)() value = getattr(obj, "get_%s_url" % field.name, lambda: None)()
else: else:
value = field.flatten_data(follow=None, obj=obj).get(field.name, "") value = field.flatten_data(follow=None, obj=obj).get(field.name, "")
return str(value) return str(value)
def start_serialization(self): def start_serialization(self):
""" """
Called when serializing of the queryset starts. Called when serializing of the queryset starts.
""" """
raise NotImplementedError raise NotImplementedError
def end_serialization(self): def end_serialization(self):
""" """
Called when serializing of the queryset ends. Called when serializing of the queryset ends.
""" """
pass pass
def start_object(self, obj): def start_object(self, obj):
""" """
Called when serializing of an object starts. Called when serializing of an object starts.
""" """
raise NotImplementedError raise NotImplementedError
def end_object(self, obj): def end_object(self, obj):
""" """
Called when serializing of an object ends. Called when serializing of an object ends.
""" """
pass pass
def handle_field(self, obj, field): def handle_field(self, obj, field):
""" """
Called to handle each individual (non-relational) field on an object. Called to handle each individual (non-relational) field on an object.
""" """
raise NotImplementedError raise NotImplementedError
def handle_fk_field(self, obj, field): def handle_fk_field(self, obj, field):
""" """
Called to handle a ForeignKey field. Called to handle a ForeignKey field.
""" """
raise NotImplementedError raise NotImplementedError
def handle_m2m_field(self, obj, field): def handle_m2m_field(self, obj, field):
""" """
Called to handle a ManyToManyField. Called to handle a ManyToManyField.
""" """
raise NotImplementedError raise NotImplementedError
def getvalue(self): def getvalue(self):
""" """
Return the fully serialized queryset. Return the fully serialized queryset.
@ -109,7 +113,7 @@ class Deserializer(object):
""" """
Abstract base deserializer class. Abstract base deserializer class.
""" """
def __init__(self, stream_or_string, **options): def __init__(self, stream_or_string, **options):
""" """
Init this serializer given a stream or a string Init this serializer given a stream or a string
@ -123,39 +127,39 @@ class Deserializer(object):
# deserialization starts (otherwise subclass calls to get_model() # deserialization starts (otherwise subclass calls to get_model()
# and friends might fail...) # and friends might fail...)
models.get_apps() models.get_apps()
def __iter__(self): def __iter__(self):
return self return self
def next(self): def next(self):
"""Iteration iterface -- return the next item in the stream""" """Iteration iterface -- return the next item in the stream"""
raise NotImplementedError raise NotImplementedError
class DeserializedObject(object): class DeserializedObject(object):
""" """
A deserialzed model. A deserialzed model.
Basically a container for holding the pre-saved deserialized data along Basically a container for holding the pre-saved deserialized data along
with the many-to-many data saved with the object. with the many-to-many data saved with the object.
Call ``save()`` to save the object (with the many-to-many data) to the Call ``save()`` to save the object (with the many-to-many data) to the
database; call ``save(save_m2m=False)`` to save just the object fields database; call ``save(save_m2m=False)`` to save just the object fields
(and not touch the many-to-many stuff.) (and not touch the many-to-many stuff.)
""" """
def __init__(self, obj, m2m_data=None): def __init__(self, obj, m2m_data=None):
self.object = obj self.object = obj
self.m2m_data = m2m_data self.m2m_data = m2m_data
def __repr__(self): def __repr__(self):
return "<DeserializedObject: %s>" % str(self.object) return "<DeserializedObject: %s>" % str(self.object)
def save(self, save_m2m=True): def save(self, save_m2m=True):
self.object.save() self.object.save()
if self.m2m_data and save_m2m: if self.m2m_data and save_m2m:
for accessor_name, object_list in self.m2m_data.items(): for accessor_name, object_list in self.m2m_data.items():
setattr(self.object, accessor_name, object_list) setattr(self.object, accessor_name, object_list)
# prevent a second (possibly accidental) call to save() from saving # prevent a second (possibly accidental) call to save() from saving
# the m2m data twice. # the m2m data twice.
self.m2m_data = None self.m2m_data = None