Index: django/db/backends/ado_mssql/base.py
===================================================================
--- django/db/backends/ado_mssql/base.py	(revision 4427)
+++ django/db/backends/ado_mssql/base.py	(working copy)
@@ -125,6 +125,9 @@
 def get_random_function_sql():
     return "RAND()"
 
+def get_deferrable_sql():
+    return " DEFERRABLE INITIALLY DEFERRED"
+
 def get_fulltext_search_sql(field_name):
     raise NotImplementedError
 
Index: django/db/backends/postgresql/base.py
===================================================================
--- django/db/backends/postgresql/base.py	(revision 4427)
+++ django/db/backends/postgresql/base.py	(working copy)
@@ -136,6 +136,9 @@
 def get_random_function_sql():
     return "RANDOM()"
 
+def get_deferrable_sql():
+    return " DEFERRABLE INITIALLY DEFERRED"
+    
 def get_fulltext_search_sql(field_name):
     raise NotImplementedError
 
Index: django/db/backends/sqlite3/base.py
===================================================================
--- django/db/backends/sqlite3/base.py	(revision 4427)
+++ django/db/backends/sqlite3/base.py	(working copy)
@@ -139,6 +139,9 @@
 def get_random_function_sql():
     return "RANDOM()"
 
+def get_deferrable_sql():
+    return ""
+
 def get_fulltext_search_sql(field_name):
     raise NotImplementedError
 
Index: django/db/backends/mysql/base.py
===================================================================
--- django/db/backends/mysql/base.py	(revision 4427)
+++ django/db/backends/mysql/base.py	(working copy)
@@ -174,6 +174,9 @@
 def get_random_function_sql():
     return "RAND()"
 
+def get_deferrable_sql():
+    return ""
+
 def get_fulltext_search_sql(field_name):
     return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name
 
Index: django/db/backends/oracle/base.py
===================================================================
--- django/db/backends/oracle/base.py	(revision 4427)
+++ django/db/backends/oracle/base.py	(working copy)
@@ -108,6 +108,9 @@
 def get_random_function_sql():
     return "DBMS_RANDOM.RANDOM"
 
+def get_deferrable_sql():
+    return " DEFERRABLE INITIALLY DEFERRED"
+
 def get_fulltext_search_sql(field_name):
     raise NotImplementedError
 
Index: django/db/backends/postgresql_psycopg2/base.py
===================================================================
--- django/db/backends/postgresql_psycopg2/base.py	(revision 4427)
+++ django/db/backends/postgresql_psycopg2/base.py	(working copy)
@@ -96,6 +96,9 @@
 def get_random_function_sql():
     return "RANDOM()"
 
+def get_deferrable_sql():
+    return " DEFERRABLE INITIALLY DEFERRED"
+
 def get_fulltext_search_sql(field_name):
     raise NotImplementedError
 
Index: django/db/backends/dummy/base.py
===================================================================
--- django/db/backends/dummy/base.py	(revision 4427)
+++ django/db/backends/dummy/base.py	(working copy)
@@ -36,6 +36,7 @@
 get_date_trunc_sql = complain
 get_limit_offset_sql = complain
 get_random_function_sql = complain
+get_deferrable_sql = complain
 get_fulltext_search_sql = complain
 get_drop_foreignkey_sql = complain
 OPERATOR_MAPPING = {}
Index: django/core/serializers/python.py
===================================================================
--- django/core/serializers/python.py	(revision 4433)
+++ django/core/serializers/python.py	(working copy)
@@ -72,15 +72,14 @@
                 pks = []
                 for pk in field_value:
                     if isinstance(pk, unicode):
-                        pk = pk.encode(options.get("encoding", settings.DEFAULT_CHARSET))
-                m2m_data[field.name] = field.rel.to._default_manager.in_bulk(field_value).values()
+                        pks.append(pk.encode(options.get("encoding", settings.DEFAULT_CHARSET)))
+                    else:
+                        pks.append(pk)
+                m2m_data[field.name] = pks
                 
             # Handle FK fields
-            elif field.rel and isinstance(field.rel, models.ManyToOneRel) and field_value is not None:
-                try:
-                    data[field.name] = field.rel.to._default_manager.get(pk=field_value)
-                except field.rel.to.DoesNotExist:
-                    data[field.name] = None
+            elif field.rel and isinstance(field.rel, models.ManyToOneRel):
+                data[field.attname] = field_value
                     
             # Handle all other fields
             else:
Index: django/core/management.py
===================================================================
--- django/core/management.py	(revision 4427)
+++ django/core/management.py	(working copy)
@@ -167,7 +167,8 @@
                 if f.rel.to in known_models:
                     field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \
                         style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)) + ' (' + \
-                        style.SQL_FIELD(backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')'
+                        style.SQL_FIELD(backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' + 
+                        backend.get_deferrable_sql()
                     )
                 else:
                     # We haven't yet created the table to which this field
@@ -210,9 +211,10 @@
                 # For MySQL, r_name must be unique in the first 64 characters.
                 # So we are careful with character usage here.
                 r_name = '%s_refs_%s_%x' % (r_col, col, abs(hash((r_table, table))))
-                final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s);' % \
+                final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \
                     (backend.quote_name(r_table), r_name,
-                    backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col)))
+                    backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col), 
+                    backend.get_deferrable_sql()))
             del pending_references[model]
     return final_output
 
@@ -232,18 +234,20 @@
                 (style.SQL_FIELD(backend.quote_name('id')),
                 style.SQL_COLTYPE(data_types['AutoField']),
                 style.SQL_KEYWORD('NOT NULL PRIMARY KEY')))
-            table_output.append('    %s %s %s %s (%s),' % \
+            table_output.append('    %s %s %s %s (%s)%s,' % \
                 (style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
                 style.SQL_COLTYPE(data_types[get_rel_data_type(opts.pk)] % opts.pk.__dict__),
                 style.SQL_KEYWORD('NOT NULL REFERENCES'),
                 style.SQL_TABLE(backend.quote_name(opts.db_table)),
-                style.SQL_FIELD(backend.quote_name(opts.pk.column))))
-            table_output.append('    %s %s %s %s (%s),' % \
+                style.SQL_FIELD(backend.quote_name(opts.pk.column)),
+                backend.get_deferrable_sql()))
+            table_output.append('    %s %s %s %s (%s)%s,' % \
                 (style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())),
                 style.SQL_COLTYPE(data_types[get_rel_data_type(f.rel.to._meta.pk)] % f.rel.to._meta.pk.__dict__),
                 style.SQL_KEYWORD('NOT NULL REFERENCES'),
                 style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)),
-                style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column))))
+                style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column)),
+                backend.get_deferrable_sql()))
             table_output.append('    %s (%s, %s)' % \
                 (style.SQL_KEYWORD('UNIQUE'),
                 style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
Index: tests/modeltests/serializers/models.py
===================================================================
--- tests/modeltests/serializers/models.py	(revision 4433)
+++ tests/modeltests/serializers/models.py	(working copy)
@@ -139,4 +139,24 @@
 ...     print obj
 <DeserializedObject: Profile of Joe>
 
+# 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"}}]'
+>>> from django.db import transaction
+>>> transaction.enter_transaction_management()
+>>> transaction.managed(True)
+>>> for obj in serializers.deserialize("json", json):
+...     obj.save()
+
+>>> transaction.commit()
+>>> transaction.leave_transaction_management()
+
+>>> article = Article.objects.get(pk=3)
+>>> article
+<Article: Forward references pose no problem>
+>>> article.categories.all()
+[<Category: Reference>, <Category: Sports>]
+>>> article.author
+<Author: Agnes>
+
 """}
