Index: django/db/models/fields/related.py
===================================================================
--- django/db/models/fields/related.py	(revision 16527)
+++ django/db/models/fields/related.py	(working copy)
@@ -258,6 +258,11 @@
             raise ValueError('Cannot assign "%r": "%s.%s" must be a "%s" instance.' %
                                 (value, instance._meta.object_name,
                                  self.related.get_accessor_name(), self.related.opts.object_name))
+        # If the related object is not already saved, it has no primary key and
+        # can not be saved.
+        elif value is not None and value.pk is None:
+            raise ValueError('Cannot assign "%r": "%s.%s" must have a primary key.' %
+                                (value, instance._meta.object_name, self.field.name))
         elif value is not None:
             if instance._state.db is None:
                 instance._state.db = router.db_for_write(instance.__class__, instance=value)
@@ -330,6 +335,11 @@
             raise ValueError('Cannot assign "%r": "%s.%s" must be a "%s" instance.' %
                                 (value, instance._meta.object_name,
                                  self.field.name, self.field.rel.to._meta.object_name))
+        # If the related object is not already saved, it has no primary key and
+        # can not be saved.
+        elif value is not None and value.pk is None:
+            raise ValueError('Cannot assign "%r": "%s.%s" must have a primary key.' %
+                                (value, instance._meta.object_name, self.field.name))
         elif value is not None:
             if instance._state.db is None:
                 instance._state.db = router.db_for_write(instance.__class__, instance=value)
Index: tests/modeltests/many_to_one/tests.py
===================================================================
--- tests/modeltests/many_to_one/tests.py	(revision 16527)
+++ tests/modeltests/many_to_one/tests.py	(working copy)
@@ -111,6 +111,15 @@
         self.assertFalse(hasattr(self.r2.article_set, 'remove'))
         self.assertFalse(hasattr(self.r2.article_set, 'clear'))
 
+        # Assign a reporter without a primary key should raise an error.
+        a = Article(headline="Carl's biography")
+        r3 = Reporter(first_name="Carl")
+        self.assertRaises(ValueError, setattr, a, 'reporter', r3)
+
+        # Assign a article without primary key to a reporter should
+        # raise an error.
+        self.assertRaises(ValueError, r3.article_set.add, a)
+
     def test_selects(self):
         new_article = self.r.article_set.create(headline="John's second story",
                                                 pub_date=datetime(2005, 7, 29))
