diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py
index a68ea21..d9d4040 100644
--- a/django/core/serializers/python.py
+++ b/django/core/serializers/python.py
@@ -27,10 +27,14 @@ class Serializer(base.Serializer):
         self._current = {}
 
     def end_object(self, obj):
+        if self.use_natural_keys and hasattr(obj, 'natural_key'):
+            pk = obj.natural_key()
+        else:
+            pk = smart_unicode(obj._get_pk_val(), strings_only=True)
         self.objects.append({
-            "model"  : smart_unicode(obj._meta),
-            "pk"     : smart_unicode(obj._get_pk_val(), strings_only=True),
-            "fields" : self._current
+            "model": smart_unicode(obj._meta),
+            "pk": pk,
+            "fields": self._current
         })
         self._current = None
 
@@ -82,7 +86,16 @@ 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 = {Model._meta.pk.attname : Model._meta.pk.to_python(d["pk"])}
+        pk = d["pk"]
+        if hasattr(Model._default_manager, 'get_by_natural_key') and\
+                                                hasattr(pk, '__iter__'):
+            try:
+                pk = Model._default_manager.db_manager(db).get_by_natural_key(*pk).pk
+            except Model.DoesNotExist:
+                pk = None
+        else:
+            pk = Model._meta.pk.to_python(pk)
+        data = {Model._meta.pk.attname: pk}
         m2m_data = {}
 
         # Handle each field
diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py
index 5fef3b6..435634d 100644
--- a/django/core/serializers/xml_serializer.py
+++ b/django/core/serializers/xml_serializer.py
@@ -42,10 +42,17 @@ class Serializer(base.Serializer):
             raise base.SerializationError("Non-model object (%s) encountered during serialization" % type(obj))
 
         self.indent(1)
-        self.xml.startElement("object", {
-            "pk"    : smart_unicode(obj._get_pk_val()),
-            "model" : smart_unicode(obj._meta),
-        })
+        natural_key = self.use_natural_keys and hasattr(obj, 'natural_key')
+        object_data = {"model": smart_unicode(obj._meta)}
+        if not natural_key:
+            object_data['pk'] = smart_unicode(obj._get_pk_val())
+        self.xml.startElement("object", object_data)
+        if natural_key:
+            for value in obj.natural_key():
+                self.indent(2)
+                self.xml.startElement("natural", {})
+                self.xml.characters(smart_unicode(value))
+                self.xml.endElement("natural")
 
     def end_object(self, obj):
         """
@@ -166,13 +173,21 @@ class Deserializer(base.Deserializer):
         # bail.
         Model = self._get_model_from_node(node, "model")
 
-        # Start building a data dictionary from the object.  If the node is
-        # missing the pk attribute, bail.
-        pk = node.getAttribute("pk")
-        if not pk:
-            raise base.DeserializationError("<object> node is missing the 'pk' attribute")
+        # Start building a data dictionary from the object.
+        natural_key = False
+        if hasattr(Model._default_manager, 'get_by_natural_key'):
+            keys = [n for n in node.childNodes if n.tagName == 'natural']
+            if keys:
+                field_value = [getInnerText(k).strip() for k in keys]
+                try:
+                    pk = Model._default_manager.db_manager(self.db).get_by_natural_key(*field_value).pk
+                except Model.DoesNotExist:
+                    pk = None
+                natural_key = True
+        if not natural_key:
+            pk = Model._meta.pk.to_python(node.getAttribute("pk"))
 
-        data = {Model._meta.pk.attname : Model._meta.pk.to_python(pk)}
+        data = {Model._meta.pk.attname: pk}
 
         # Also start building a dict of m2m data (this is saved as
         # {m2m_accessor_attribute : [list_of_related_objects]})
