diff --git a/django/db/models/base.py b/django/db/models/base.py
index b679d08..a4aa477 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -625,6 +625,15 @@ class Model(six.with_metaclass(ModelBase)):
         that the "save" must be an SQL insert or update (or equivalent for
         non-SQL backends), respectively. Normally, they should not be set.
         """
+        for field in self._meta.concrete_fields + self._meta.related_objects:
+            if field.is_relation:
+                obj =  getattr(self, field.name, None)
+                if obj and obj._state.adding:
+                    raise ValueError(
+                        "save() prohibited to prevent data loss due to "
+                        "unsaved related object '%s'." % field.name
+                    )
+
         using = using or router.db_for_write(self.__class__, instance=self)
         if force_insert and (force_update or update_fields):
             raise ValueError("Cannot force both insert and updating in model saving.")
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index b038fdf..77a79d4 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -514,11 +514,6 @@ class SingleRelatedObjectDescriptor(object):
                     raise ValueError('Cannot assign "%r": the current database router prevents this relation.' % value)
 
         related_pk = tuple(getattr(instance, field.attname) for field in self.related.field.foreign_related_fields)
-        if not self.related.field.allow_unsaved_instance_assignment and None in related_pk:
-            raise ValueError(
-                'Cannot assign "%r": "%s" instance isn\'t saved in the database.' %
-                (value, instance._meta.object_name)
-            )
 
         # Set the value of the related field to the value of the related object's related field
         for index, field in enumerate(self.related.field.local_related_fields):
@@ -685,11 +680,6 @@ class ReverseSingleRelatedObjectDescriptor(object):
         else:
             for lh_field, rh_field in self.field.related_fields:
                 pk = value._get_pk_val()
-                if not self.field.allow_unsaved_instance_assignment and pk is None:
-                    raise ValueError(
-                        'Cannot assign "%r": "%s" instance isn\'t saved in the database.' %
-                        (value, self.field.remote_field.model._meta.object_name)
-                    )
                 setattr(instance, lh_field.attname, getattr(value, rh_field.attname))
 
         # Since we already know what the related object is, seed the related
@@ -1579,7 +1569,6 @@ class ForeignObject(RelatedField):
     one_to_many = False
     one_to_one = False
 
-    allow_unsaved_instance_assignment = False
     requires_unique_target = True
     related_accessor_class = ForeignRelatedObjectsDescriptor
     rel_class = ForeignObjectRel
diff --git a/tests/many_to_one/tests.py b/tests/many_to_one/tests.py
index d828abe..c1222ce 100644
--- a/tests/many_to_one/tests.py
+++ b/tests/many_to_one/tests.py
@@ -566,7 +566,7 @@ class ManyToOneTests(TestCase):
         with self.assertRaisesMessage(ValueError,
                 'Cannot assign "%r": "%s" instance isn\'t saved in the database.'
                 % (p, Child.parent.field.remote_field.model._meta.object_name)):
-            Child(parent=p)
+            Child(parent=p).save()
 
         with self.assertRaisesMessage(ValueError,
                 'Cannot assign "%r": "%s" instance isn\'t saved in the database.'
diff --git a/tests/one_to_one/tests.py b/tests/one_to_one/tests.py
index 041fe68..01a489d 100644
--- a/tests/one_to_one/tests.py
+++ b/tests/one_to_one/tests.py
@@ -134,16 +134,15 @@ class OneToOneTests(TestCase):
         should raise an exception.
         """
         place = Place(name='User', address='London')
-        with self.assertRaisesMessage(ValueError,
-                            'Cannot assign "%r": "%s" instance isn\'t saved in the database.'
-                            % (place, Restaurant.place.field.remote_field.model._meta.object_name)):
+        msg = "save() prohibited to prevent data loss due to unsaved related object 'place'."
+        with self.assertRaisesMessage(ValueError, msg):
             Restaurant.objects.create(place=place, serves_hot_dogs=True, serves_pizza=False)
         bar = UndergroundBar()
         p = Place(name='User', address='London')
-        with self.assertRaisesMessage(ValueError,
-                            'Cannot assign "%r": "%s" instance isn\'t saved in the database.'
-                            % (bar, p._meta.object_name)):
+        msg = "save() prohibited to prevent data loss due to unsaved related object 'undergroundbar'."
+        with self.assertRaisesMessage(ValueError, msg):
             p.undergroundbar = bar
+            p.save()
 
     def test_unsaved_object_check_override(self):
         """
