diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py index f61a2fa4a2..6fc13d76b5 100644 --- a/django/core/serializers/python.py +++ b/django/core/serializers/python.py @@ -27,13 +27,13 @@ class Serializer(base.Serializer): def end_object(self, obj): self.objects.append({ "model" : smart_unicode(obj._meta), - "pk" : smart_unicode(obj._get_pk_val()), + "pk" : smart_unicode(obj._get_pk_val(), strings_only=True), "fields" : self._current }) self._current = None def handle_field(self, obj, field): - self._current[field.name] = getattr(obj, field.name) + self._current[field.name] = smart_unicode(getattr(obj, field.name), strings_only=True) def handle_fk_field(self, obj, field): related = getattr(obj, field.name) @@ -44,10 +44,11 @@ class Serializer(base.Serializer): else: # Related to remote object via other field related = getattr(related, field.rel.field_name) - self._current[field.name] = related + self._current[field.name] = smart_unicode(related, strings_only=True) def handle_m2m_field(self, obj, field): - self._current[field.name] = [related._get_pk_val() for related in getattr(obj, field.name).iterator()] + self._current[field.name] = [smart_unicode(related._get_pk_val(), strings_only=True) + for related in getattr(obj, field.name).iterator()] def getvalue(self): return self.objects diff --git a/tests/modeltests/fixtures/models.py b/tests/modeltests/fixtures/models.py index b59c388bbd..a1e2446e56 100644 --- a/tests/modeltests/fixtures/models.py +++ b/tests/modeltests/fixtures/models.py @@ -74,7 +74,7 @@ Multiple fixtures named 'fixture2' in '...fixtures'. Aborting. # Dump the current contents of the database as a JSON fixture >>> management.call_command('dumpdata', 'fixtures', format='json') -[{"pk": "3", "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": "2", "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": "1", "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}] +[{"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}] """} from django.test import TestCase diff --git a/tests/modeltests/serializers/models.py b/tests/modeltests/serializers/models.py index 2ee6cfce67..a0a68d4bcc 100644 --- a/tests/modeltests/serializers/models.py +++ b/tests/modeltests/serializers/models.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ 41. Serialization @@ -43,6 +44,25 @@ class AuthorProfile(models.Model): def __unicode__(self): return u"Profile of %s" % self.author + +class Actor(models.Model): + name = models.CharField(max_length=20, primary_key=True) + + class Meta: + ordering = ('name',) + + def __unicode__(self): + return self.name + +class Movie(models.Model): + actor = models.ForeignKey(Actor) + title = models.CharField(max_length=50) + + class Meta: + ordering = ('title',) + + def __unicode__(self): + return self.title __test__ = {'API_TESTS':""" # Create some data: @@ -101,7 +121,7 @@ __test__ = {'API_TESTS':""" # Django also ships with a built-in JSON serializers >>> json = serializers.serialize("json", Category.objects.filter(pk=2)) >>> json -'[{"pk": "2", "model": "serializers.category", "fields": {"name": "Music"}}]' +'[{"pk": 2, "model": "serializers.category", "fields": {"name": "Music"}}]' # You can easily create new objects by deserializing data with an empty PK # (It's easier to demo this with JSON...) @@ -133,7 +153,7 @@ __test__ = {'API_TESTS':""" >>> json = serializers.serialize("json", AuthorProfile.objects.all()) >>> json -'[{"pk": "1", "model": "serializers.authorprofile", "fields": {"date_of_birth": "1970-01-01"}}]' +'[{"pk": 1, "model": "serializers.authorprofile", "fields": {"date_of_birth": "1970-01-01"}}]' >>> for obj in serializers.deserialize("json", json): ... print obj @@ -141,7 +161,7 @@ __test__ = {'API_TESTS':""" # Objects ids can be referenced before they are defined in the serialization data # However, the deserialization process will need to be contained within a transaction ->>> json = '[{"pk": "3", "model": "serializers.article", "fields": {"headline": "Forward references pose no problem", "pub_date": "2006-06-16 15:00:00", "categories": [4, 1], "author": 4}}, {"pk": "4", "model": "serializers.category", "fields": {"name": "Reference"}}, {"pk": "4", "model": "serializers.author", "fields": {"name": "Agnes"}}]' +>>> json = '[{"pk": 3, "model": "serializers.article", "fields": {"headline": "Forward references pose no problem", "pub_date": "2006-06-16 15:00:00", "categories": [4, 1], "author": 4}}, {"pk": 4, "model": "serializers.category", "fields": {"name": "Reference"}}, {"pk": 4, "model": "serializers.author", "fields": {"name": "Agnes"}}]' >>> from django.db import transaction >>> transaction.enter_transaction_management() >>> transaction.managed(True) @@ -161,6 +181,30 @@ __test__ = {'API_TESTS':""" # Serializer output can be restricted to a subset of fields >>> print serializers.serialize("json", Article.objects.all(), fields=('headline','pub_date')) -[{"pk": "1", "model": "serializers.article", "fields": {"headline": "Just kidding; I love TV poker", "pub_date": "2006-06-16 11:00:00"}}, {"pk": "2", "model": "serializers.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": "3", "model": "serializers.article", "fields": {"headline": "Forward references pose no problem", "pub_date": "2006-06-16 15:00:00"}}] +[{"pk": 1, "model": "serializers.article", "fields": {"headline": "Just kidding; I love TV poker", "pub_date": "2006-06-16 11:00:00"}}, {"pk": 2, "model": "serializers.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 3, "model": "serializers.article", "fields": {"headline": "Forward references pose no problem", "pub_date": "2006-06-16 15:00:00"}}] + +# Every string is serialized as a unicode object, also primary key +# which is 'varchar' +>>> ac = Actor(name="Zażółć") +>>> mv = Movie(title="Gęślą jaźń", actor=ac) +>>> ac.save(); mv.save() + +# Let's serialize our movie +>>> print serializers.serialize("json", [mv]) +[{"pk": 1, "model": "serializers.movie", "fields": {"actor": "Za\u017c\u00f3\u0142\u0107", "title": "G\u0119\u015bl\u0105 ja\u017a\u0144"}}] + +# Deserialization of movie +>>> list(serializers.deserialize('json', serializers.serialize('json', [mv])))[0].object.title +u'G\u0119\u015bl\u0105 ja\u017a\u0144' + +# None is null after serialization to json +# Primary key is None in case of not saved model +>>> mv2 = Movie(title="Movie 2", actor=ac) +>>> print serializers.serialize("json", [mv2]) +[{"pk": null, "model": "serializers.movie", "fields": {"actor": "Za\u017c\u00f3\u0142\u0107", "title": "Movie 2"}}] + +# Deserialization of null returns None for pk +>>> print list(serializers.deserialize('json', serializers.serialize('json', [mv2])))[0].object.id +None """}