Fixed #4714 -- Modified serializers to handle None primary keys correctly. This slightly changes the output format for primary keys on JSON and YAML serializers (PKs will be output as 1, rather than "1". However, fixtures in the old format will still load ok. Thanks for the patch, pigletto.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@6264 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
604504896c
commit
314536190b
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
41. Serialization
|
||||
|
||||
|
@ -44,6 +45,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:
|
||||
>>> from datetime import datetime
|
||||
|
@ -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
|
||||
|
||||
"""}
|
||||
|
|
Loading…
Reference in New Issue