1
0
mirror of https://github.com/django/django.git synced 2025-07-04 17:59:13 +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: except ImportError:
from StringIO import StringIO from StringIO import StringIO
from django.db import models from django.db import models
from django.utils.encoding import smart_str, smart_unicode
class SerializationError(Exception): class SerializationError(Exception):
"""Something bad happened during serialization.""" """Something bad happened during serialization."""
@ -59,7 +60,7 @@ class Serializer(object):
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 smart_unicode(value)
def start_serialization(self): def start_serialization(self):
""" """
@ -154,7 +155,7 @@ class DeserializedObject(object):
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>" % smart_str(self.object)
def save(self, save_m2m=True): def save(self, save_m2m=True):
self.object.save() self.object.save()

View File

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

View File

@ -6,6 +6,7 @@ from django.conf import settings
from django.core.serializers import base from django.core.serializers import base
from django.db import models from django.db import models
from django.utils.xmlutils import SimplerXMLGenerator from django.utils.xmlutils import SimplerXMLGenerator
from django.utils.encoding import smart_unicode
from xml.dom import pulldom from xml.dom import pulldom
class Serializer(base.Serializer): class Serializer(base.Serializer):
@ -42,8 +43,8 @@ class Serializer(base.Serializer):
self.indent(1) self.indent(1)
self.xml.startElement("object", { self.xml.startElement("object", {
"pk" : str(obj._get_pk_val()), "pk" : smart_unicode(obj._get_pk_val()),
"model" : str(obj._meta), "model" : smart_unicode(obj._meta),
}) })
def end_object(self, obj): def end_object(self, obj):
@ -68,7 +69,7 @@ class Serializer(base.Serializer):
# serializer base class). # serializer base class).
if getattr(obj, field.name) is not None: if getattr(obj, field.name) is not None:
value = self.get_string_value(obj, field) value = self.get_string_value(obj, field)
self.xml.characters(str(value)) self.xml.characters(smart_unicode(value))
else: else:
self.xml.addQuickElement("None") self.xml.addQuickElement("None")
@ -82,7 +83,7 @@ class Serializer(base.Serializer):
self._start_relational_field(field) self._start_relational_field(field)
related = getattr(obj, field.name) related = getattr(obj, field.name)
if related is not None: 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: else:
self.xml.addQuickElement("None") self.xml.addQuickElement("None")
self.xml.endElement("field") self.xml.endElement("field")
@ -95,7 +96,7 @@ class Serializer(base.Serializer):
""" """
self._start_relational_field(field) self._start_relational_field(field)
for relobj in getattr(obj, field.name).iterator(): 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") self.xml.endElement("field")
def _start_relational_field(self, field): def _start_relational_field(self, field):
@ -106,7 +107,7 @@ class Serializer(base.Serializer):
self.xml.startElement("field", { self.xml.startElement("field", {
"name" : field.name, "name" : field.name,
"rel" : field.rel.__class__.__name__, "rel" : field.rel.__class__.__name__,
"to" : str(field.rel.to._meta), "to" : smart_unicode(field.rel.to._meta),
}) })
class Deserializer(base.Deserializer): class Deserializer(base.Deserializer):
@ -116,7 +117,6 @@ class Deserializer(base.Deserializer):
def __init__(self, stream_or_string, **options): def __init__(self, stream_or_string, **options):
super(Deserializer, self).__init__(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) self.event_stream = pulldom.parse(self.stream)
def next(self): def next(self):
@ -130,7 +130,8 @@ class Deserializer(base.Deserializer):
""" """
Convert an <object> node to a DeserializedObject. 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") Model = self._get_model_from_node(node, "model")
# Start building a data dictionary from the object. If the node is # 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': if len(field_node.childNodes) == 1 and field_node.childNodes[0].nodeName == 'None':
value = None value = None
else: else:
value = field.to_python(getInnerText(field_node).strip().encode(self.encoding)) value = field.to_python(getInnerText(field_node).strip())
data[field.name] = value data[field.name] = value
# Return a DeserializedObject so that the m2m data has a place to live. # Return a DeserializedObject so that the m2m data has a place to live.
@ -182,14 +183,14 @@ class Deserializer(base.Deserializer):
return None return None
else: else:
return field.rel.to._meta.get_field(field.rel.field_name).to_python( 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): 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( return [field.rel.to._meta.pk.to_python(
c.getAttribute("pk").encode(self.encoding)) c.getAttribute("pk"))
for c in node.getElementsByTagName("object")] for c in node.getElementsByTagName("object")]
def _get_model_from_node(self, node, attr): def _get_model_from_node(self, node, attr):
@ -226,4 +227,5 @@ def getInnerText(node):
inner_text.extend(getInnerText(child)) inner_text.extend(getInnerText(child))
else: else:
pass 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, 13, CharData, "null"),
(data_obj, 14, CharData, "NULL"), (data_obj, 14, CharData, "NULL"),
(data_obj, 15, CharData, None), (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, 20, DateData, datetime.date(2006,6,16)),
(data_obj, 21, DateData, None), (data_obj, 21, DateData, None),
(data_obj, 30, DateTimeData, datetime.datetime(2006,6,16,10,42,37)), (data_obj, 30, DateTimeData, datetime.datetime(2006,6,16,10,42,37)),