1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

unicode: Made the serializers unicode-aware. Refs #3878, #4227.

git-svn-id: http://code.djangoproject.com/svn/django/branches/unicode@5248 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-05-15 16:14:55 +00:00
parent 0e4c3838ab
commit 9d001fa7f9
6 changed files with 103 additions and 102 deletions

View File

@ -7,6 +7,7 @@ try:
except ImportError:
from StringIO import StringIO
from django.db import models
from django.utils.encoding import smart_str, smart_unicode
class SerializationError(Exception):
"""Something bad happened during serialization."""
@ -59,7 +60,7 @@ class Serializer(object):
value = getattr(obj, "get_%s_url" % field.name, lambda: None)()
else:
value = field.flatten_data(follow=None, obj=obj).get(field.name, "")
return str(value)
return smart_unicode(value)
def start_serialization(self):
"""
@ -154,7 +155,7 @@ class DeserializedObject(object):
self.m2m_data = m2m_data
def __repr__(self):
return "<DeserializedObject: %s>" % str(self.object)
return "<DeserializedObject: %s>" % smart_str(self.object)
def save(self, save_m2m=True):
self.object.save()

View File

@ -7,6 +7,7 @@ other serializers.
from django.conf import settings
from django.core.serializers import base
from django.db import models
from django.utils.encoding import smart_unicode
class Serializer(base.Serializer):
"""
@ -25,8 +26,8 @@ class Serializer(base.Serializer):
def end_object(self, obj):
self.objects.append({
"model" : str(obj._meta),
"pk" : str(obj._get_pk_val()),
"model" : smart_unicode(obj._meta),
"pk" : smart_unicode(obj._get_pk_val()),
"fields" : self._current
})
self._current = None
@ -62,21 +63,15 @@ def Deserializer(object_list, **options):
# Handle each field
for (field_name, field_value) in d["fields"].iteritems():
if isinstance(field_value, unicode):
field_value = field_value.encode(options.get("encoding", settings.DEFAULT_CHARSET))
if isinstance(field_value, str):
field_value = smart_unicode(field_value, options.get("encoding", settings.DEFAULT_CHARSET))
field = Model._meta.get_field(field_name)
# Handle M2M relations
if field.rel and isinstance(field.rel, models.ManyToManyRel):
pks = []
m2m_convert = field.rel.to._meta.pk.to_python
for pk in field_value:
if isinstance(pk, unicode):
pks.append(m2m_convert(pk.encode(options.get("encoding", settings.DEFAULT_CHARSET))))
else:
pks.append(m2m_convert(pk))
m2m_data[field.name] = pks
m2m_data[field.name] = [m2m_convert(smart_unicode(pk)) for pk in field_value]
# Handle FK fields
elif field.rel and isinstance(field.rel, models.ManyToOneRel):
@ -100,5 +95,5 @@ def _get_model(model_identifier):
except TypeError:
Model = None
if Model is None:
raise base.DeserializationError("Invalid model identifier: '%s'" % model_identifier)
raise base.DeserializationError(u"Invalid model identifier: '%s'" % model_identifier)
return Model

View File

@ -6,6 +6,7 @@ from django.conf import settings
from django.core.serializers import base
from django.db import models
from django.utils.xmlutils import SimplerXMLGenerator
from django.utils.encoding import smart_unicode
from xml.dom import pulldom
class Serializer(base.Serializer):
@ -42,8 +43,8 @@ class Serializer(base.Serializer):
self.indent(1)
self.xml.startElement("object", {
"pk" : str(obj._get_pk_val()),
"model" : str(obj._meta),
"pk" : smart_unicode(obj._get_pk_val()),
"model" : smart_unicode(obj._meta),
})
def end_object(self, obj):
@ -68,7 +69,7 @@ class Serializer(base.Serializer):
# serializer base class).
if getattr(obj, field.name) is not None:
value = self.get_string_value(obj, field)
self.xml.characters(str(value))
self.xml.characters(smart_unicode(value))
else:
self.xml.addQuickElement("None")
@ -82,7 +83,7 @@ class Serializer(base.Serializer):
self._start_relational_field(field)
related = getattr(obj, field.name)
if related is not None:
self.xml.characters(str(getattr(related, field.rel.field_name)))
self.xml.characters(smart_unicode(getattr(related, field.rel.field_name)))
else:
self.xml.addQuickElement("None")
self.xml.endElement("field")
@ -95,7 +96,7 @@ class Serializer(base.Serializer):
"""
self._start_relational_field(field)
for relobj in getattr(obj, field.name).iterator():
self.xml.addQuickElement("object", attrs={"pk" : str(relobj._get_pk_val())})
self.xml.addQuickElement("object", attrs={"pk" : smart_unicode(relobj._get_pk_val())})
self.xml.endElement("field")
def _start_relational_field(self, field):
@ -106,7 +107,7 @@ class Serializer(base.Serializer):
self.xml.startElement("field", {
"name" : field.name,
"rel" : field.rel.__class__.__name__,
"to" : str(field.rel.to._meta),
"to" : smart_unicode(field.rel.to._meta),
})
class Deserializer(base.Deserializer):
@ -116,7 +117,6 @@ class Deserializer(base.Deserializer):
def __init__(self, stream_or_string, **options):
super(Deserializer, self).__init__(stream_or_string, **options)
self.encoding = self.options.get("encoding", settings.DEFAULT_CHARSET)
self.event_stream = pulldom.parse(self.stream)
def next(self):
@ -130,7 +130,8 @@ class Deserializer(base.Deserializer):
"""
Convert an <object> node to a DeserializedObject.
"""
# Look up the model using the model loading mechanism. If this fails, bail.
# Look up the model using the model loading mechanism. If this fails,
# bail.
Model = self._get_model_from_node(node, "model")
# Start building a data dictionary from the object. If the node is
@ -167,7 +168,7 @@ class Deserializer(base.Deserializer):
if len(field_node.childNodes) == 1 and field_node.childNodes[0].nodeName == 'None':
value = None
else:
value = field.to_python(getInnerText(field_node).strip().encode(self.encoding))
value = field.to_python(getInnerText(field_node).strip())
data[field.name] = value
# Return a DeserializedObject so that the m2m data has a place to live.
@ -182,14 +183,14 @@ class Deserializer(base.Deserializer):
return None
else:
return field.rel.to._meta.get_field(field.rel.field_name).to_python(
getInnerText(node).strip().encode(self.encoding))
getInnerText(node).strip())
def _handle_m2m_field_node(self, node, field):
"""
Handle a <field> node for a ManyToManyField
Handle a <field> node for a ManyToManyField.
"""
return [field.rel.to._meta.pk.to_python(
c.getAttribute("pk").encode(self.encoding))
c.getAttribute("pk"))
for c in node.getElementsByTagName("object")]
def _get_model_from_node(self, node, attr):
@ -226,4 +227,5 @@ def getInnerText(node):
inner_text.extend(getInnerText(child))
else:
pass
return "".join(inner_text)
return u"".join(inner_text)

View File

@ -105,6 +105,9 @@ test_data = [
(data_obj, 13, CharData, "null"),
(data_obj, 14, CharData, "NULL"),
(data_obj, 15, CharData, None),
# (We use something that will fit into a latin1 database encoding here,
# because that is still the default used on many system setups.)
(data_obj, 16, CharData, u'\xa5'),
(data_obj, 20, DateData, datetime.date(2006,6,16)),
(data_obj, 21, DateData, None),
(data_obj, 30, DateTimeData, datetime.datetime(2006,6,16,10,42,37)),