Index: django/db/models/fields/related.py
===================================================================
--- django/db/models/fields/related.py	(revision 17889)
+++ django/db/models/fields/related.py	(working copy)
@@ -249,12 +249,20 @@
         if instance is None:
             return self
         try:
-            return getattr(instance, self.cache_name)
+            related = getattr(instance, self.cache_name)
         except AttributeError:
             params = {'%s__pk' % self.related.field.name: instance._get_pk_val()}
-            rel_obj = self.get_query_set(instance=instance).get(**params)
-            setattr(instance, self.cache_name, rel_obj)
-            return rel_obj
+            try:
+                related = self.get_query_set(instance=instance).get(**params)
+            except self.related.model.DoesNotExist:
+                related = None
+            else:
+                setattr(related, self.related.field.get_cache_name(), instance)
+            setattr(instance, self.cache_name, related)
+        if related is None:
+            raise self.related.model.DoesNotExist
+        else:
+            return related
 
     def __set__(self, instance, value):
         if instance is None:
@@ -331,7 +339,6 @@
     def __get__(self, instance, instance_type=None):
         if instance is None:
             return self
-
         try:
             return getattr(instance, self.cache_name)
         except AttributeError:
@@ -347,6 +354,7 @@
             else:
                 params = {'%s__exact' % self.field.rel.field_name: val}
             qs = self.get_query_set(instance=instance)
+            # Assuming the database enforces foreign keys, this won't fail.
             rel_obj = qs.get(**params)
             setattr(instance, self.cache_name, rel_obj)
             return rel_obj
@@ -385,7 +393,7 @@
             # populated the cache, then we don't care - we're only accessing
             # the object to invalidate the accessor cache, so there's no
             # need to populate the cache just to expire it again.
-            related = getattr(instance, self.field.get_cache_name(), None)
+            related = getattr(instance, self.cache_name, None)
 
             # If we've got an old related object, we need to clear out its
             # cache. This cache also might not exist if the related object
@@ -405,9 +413,11 @@
         setattr(instance, self.field.attname, val)
 
         # Since we already know what the related object is, seed the related
-        # object cache now, too. This avoids another db hit if you get the
+        # object caches now, too. This avoids another db hit if you get the
         # object you just set.
-        setattr(instance, self.field.get_cache_name(), value)
+        setattr(instance, self.cache_name, value)
+        if value is not None and not self.field.rel.multiple:
+            setattr(value, self.field.related.get_cache_name(), instance)
 
 class ForeignRelatedObjectsDescriptor(object):
     # This class provides the functionality that makes the related-object
Index: tests/regressiontests/select_related_onetoone/tests.py
===================================================================
--- tests/regressiontests/select_related_onetoone/tests.py	(revision 17889)
+++ tests/regressiontests/select_related_onetoone/tests.py	(working copy)
@@ -79,4 +79,32 @@
         p1 = Product.objects.create(name="Django Plushie", image=im)
         p2 = Product.objects.create(name="Talking Django Plushie")
 
-        self.assertEqual(len(Product.objects.select_related("image")), 2)
+        with self.assertNumQueries(1):
+            result = sorted(Product.objects.select_related("image"), key=lambda x: x.name)
+            self.assertEqual([p.name for p in result], ["Django Plushie", "Talking Django Plushie"])
+
+            self.assertEqual(p1.image, im)
+            # Check for ticket #13839
+            self.assertIsNone(p2.image)
+
+    def test_missing_reverse(self):
+        """
+        Ticket #13839: select_related() should NOT cache None
+        for missing objects on a reverse 1-1 relation.
+        """
+        with self.assertNumQueries(1):
+            user = User.objects.select_related('userprofile').get(username='bob')
+            with self.assertRaises(UserProfile.DoesNotExist):
+                user.userprofile
+
+    def test_nullable_missing_reverse(self):
+        """
+        Ticket #13839: select_related() should NOT cache None
+        for missing objects on a reverse 0-1 relation.
+        """
+        Image.objects.create(name="imag1")
+
+        with self.assertNumQueries(1):
+            image = Image.objects.select_related('product').get()
+            with self.assertRaises(Product.DoesNotExist):
+                image.product
