diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py index 9f535e3ba8..190636e670 100644 --- a/django/core/serializers/base.py +++ b/django/core/serializers/base.py @@ -170,21 +170,3 @@ class DeserializedObject(object): # prevent a second (possibly accidental) call to save() from saving # the m2m data twice. self.m2m_data = None - -def build_instance(Model, data, db): - """ - Build a model instance. - - If the model instance doesn't have a primary key and the model supports - natural keys, try to retrieve it from the database. - """ - obj = Model(**data) - if obj.pk is None and hasattr(Model, 'natural_key') and\ - hasattr(Model._default_manager, 'get_by_natural_key'): - pk = obj.natural_key() - try: - obj.pk = Model._default_manager.db_manager(db)\ - .get_by_natural_key(*pk).pk - except Model.DoesNotExist: - pass - return obj diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py index 839fee12a9..a68ea21f78 100644 --- a/django/core/serializers/python.py +++ b/django/core/serializers/python.py @@ -27,13 +27,11 @@ class Serializer(base.Serializer): self._current = {} def end_object(self, obj): - data = { - "model": smart_unicode(obj._meta), - "fields": self._current - } - if not self.use_natural_keys or not hasattr(obj, 'natural_key'): - data['pk'] = smart_unicode(obj._get_pk_val(), strings_only=True) - self.objects.append(data) + self.objects.append({ + "model" : smart_unicode(obj._meta), + "pk" : smart_unicode(obj._get_pk_val(), strings_only=True), + "fields" : self._current + }) self._current = None def handle_field(self, obj, field): @@ -84,9 +82,7 @@ def Deserializer(object_list, **options): for d in object_list: # Look up the model and starting build a dict of data for it. Model = _get_model(d["model"]) - data = {} - if 'pk' in d: - data[Model._meta.pk.attname] = Model._meta.pk.to_python(d['pk']) + data = {Model._meta.pk.attname : Model._meta.pk.to_python(d["pk"])} m2m_data = {} # Handle each field @@ -131,9 +127,7 @@ def Deserializer(object_list, **options): else: data[field.name] = field.to_python(field_value) - obj = base.build_instance(Model, data, db) - - yield base.DeserializedObject(obj, m2m_data) + yield base.DeserializedObject(Model(**data), m2m_data) def _get_model(model_identifier): """ diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py index 36e3404988..bcf5631e00 100644 --- a/django/core/serializers/xml_serializer.py +++ b/django/core/serializers/xml_serializer.py @@ -42,12 +42,16 @@ class Serializer(base.Serializer): raise base.SerializationError("Non-model object (%s) encountered during serialization" % type(obj)) self.indent(1) - object_data = {"model": smart_unicode(obj._meta)} - if not self.use_natural_keys or not hasattr(obj, 'natural_key'): - obj_pk = obj._get_pk_val() - if obj_pk is not None: - object_data['pk'] = smart_unicode(obj_pk) - self.xml.startElement("object", object_data) + obj_pk = obj._get_pk_val() + if obj_pk is None: + attrs = {"model": smart_unicode(obj._meta),} + else: + attrs = { + "pk": smart_unicode(obj._get_pk_val()), + "model": smart_unicode(obj._meta), + } + + self.xml.startElement("object", attrs) def end_object(self, obj): """ @@ -169,10 +173,13 @@ class Deserializer(base.Deserializer): Model = self._get_model_from_node(node, "model") # Start building a data dictionary from the object. - data = {} - if node.hasAttribute('pk'): - data[Model._meta.pk.attname] = Model._meta.pk.to_python( - node.getAttribute('pk')) + # If the node is missing the pk set it to None + if node.hasAttribute("pk"): + pk = node.getAttribute("pk") + else: + pk = None + + data = {Model._meta.pk.attname : Model._meta.pk.to_python(pk)} # Also start building a dict of m2m data (this is saved as # {m2m_accessor_attribute : [list_of_related_objects]}) @@ -203,10 +210,8 @@ class Deserializer(base.Deserializer): value = field.to_python(getInnerText(field_node).strip()) data[field.name] = value - obj = base.build_instance(Model, data, self.db) - # Return a DeserializedObject so that the m2m data has a place to live. - return base.DeserializedObject(obj, m2m_data) + return base.DeserializedObject(Model(**data), m2m_data) def _handle_fk_field_node(self, node, field): """ diff --git a/docs/topics/serialization.txt b/docs/topics/serialization.txt index 358f869a07..c8acc8539e 100644 --- a/docs/topics/serialization.txt +++ b/docs/topics/serialization.txt @@ -307,12 +307,6 @@ into the primary key of an actual ``Person`` object. fields will be effectively unique, you can still use those fields as a natural key. -.. versionchanged:: 1.3 - -Deserialization of objects with no primary key will always check whether the -model's manager has a ``get_by_natural_key()`` method and if so, use it to -populate the deserialized object's primary key. - Serialization of natural keys ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -359,23 +353,6 @@ use the `--natural` command line flag to generate natural keys. natural keys during serialization, but *not* be able to load those key values, just don't define the ``get_by_natural_key()`` method. -.. versionchanged:: 1.3 - -When ``use_natural_keys=True`` is specified, the primary key is no longer -provided in the serialized data of this object since it can be calculated -during deserialization:: - - ... - { - "model": "store.person", - "fields": { - "first_name": "Douglas", - "last_name": "Adams", - "birth_date": "1952-03-11", - } - } - ... - Dependencies during serialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/regressiontests/serializers_regress/models.py b/tests/regressiontests/serializers_regress/models.py index 32c55c0707..bec0a98202 100644 --- a/tests/regressiontests/serializers_regress/models.py +++ b/tests/regressiontests/serializers_regress/models.py @@ -264,17 +264,3 @@ class LengthModel(models.Model): def __len__(self): return self.data - -#Tests for natural keys. -class BookManager(models.Manager): - def get_by_natural_key(self, isbn13): - return self.get(isbn13=isbn13) - -class Book(models.Model): - isbn13 = models.CharField(max_length=14) - title = models.CharField(max_length=100) - - objects = BookManager() - - def natural_key(self): - return (self.isbn13,) diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py index 12cc4f9bf2..4180143e21 100644 --- a/tests/regressiontests/serializers_regress/tests.py +++ b/tests/regressiontests/serializers_regress/tests.py @@ -414,36 +414,8 @@ def streamTest(format, self): self.assertEqual(string_data, stream.getvalue()) stream.close() -def naturalKeyTest(format, self): - book1 = {'isbn13': '978-1590597255', 'title': 'The Definitive Guide to ' - 'Django: Web Development Done Right'} - book2 = {'isbn13':'978-1590599969', 'title': 'Practical Django Projects'} - - # Create the books. - adrian = Book.objects.create(**book1) - james = Book.objects.create(**book2) - - # Serialize the books. - string_data = serializers.serialize(format, Book.objects.all(), indent=2, - use_natural_keys=True) - - # Delete one book (to prove that the natural key generation will only - # restore the primary keys of books found in the database via the - # get_natural_key manager method). - james.delete() - - # Deserialize and test. - books = list(serializers.deserialize(format, string_data)) - self.assertEqual(len(books), 2) - self.assertEqual(books[0].object.title, book1['title']) - self.assertEqual(books[0].object.pk, adrian.pk) - self.assertEqual(books[1].object.title, book2['title']) - self.assertEqual(books[1].object.pk, None) - for format in serializers.get_serializer_formats(): setattr(SerializerTests, 'test_' + format + '_serializer', curry(serializerTest, format)) setattr(SerializerTests, 'test_' + format + '_serializer_fields', curry(fieldsTest, format)) - setattr(SerializerTests, 'test_' + format + '_serializer_natural_key', - curry(naturalKeyTest, format)) if format != 'python': setattr(SerializerTests, 'test_' + format + '_serializer_stream', curry(streamTest, format))