Index: django/db/models/sql/query.py
===================================================================
--- django/db/models/sql/query.py	(revision 7601)
+++ django/db/models/sql/query.py	(working copy)
@@ -909,12 +909,41 @@
                 next = requested.get(f.name, {})
             else:
                 next = False
-            if f.null is not None:
+            if nullable is not None:
+                new_nullable = nullable
+            else:
                 new_nullable = f.null
-            else:
-                new_nullable = None
             self.fill_related_selections(f.rel.to._meta, alias, cur_depth + 1,
                     used, next, restricted, new_nullable)
+            
+        # Do reverse columns, but only the ones in the requested list.
+        if restricted:
+            related_fields = [(x.field, x.model) for x in opts.get_all_related_objects() if x.field.unique]
+            for f, model in related_fields:
+                if f.rel.parent_link or f.related_query_name() not in requested:
+                    continue
+                table = model._meta.db_table
+                if nullable or f.null:
+                    promote = True
+                else:
+                    promote = False
+                alias = root_alias
+                alias = self.join((alias, table, f.rel.get_related_field().column,
+                        f.column), exclusions=used,
+                        promote=promote, reuse=used)
+                used.add(alias)
+    
+                self.related_select_cols.extend([(alias, f2.column)
+                        for f2 in model._meta.fields])
+                self.related_select_fields.extend(model._meta.fields)
+    
+                next = requested.get(f.related_query_name(), {})
+                if nullable is not None:
+                    new_nullable = nullable
+                else:
+                    new_nullable = f.null
+                self.fill_related_selections(model._meta, table, cur_depth + 1,
+                        used, next, restricted, new_nullable)
 
     def add_filter(self, filter_expr, connector=AND, negate=False, trim=False,
             can_reuse=None):
Index: django/db/models/query.py
===================================================================
--- django/db/models/query.py	(revision 7601)
+++ django/db/models/query.py	(working copy)
@@ -673,6 +673,29 @@
         if cached_row:
             rel_obj, index_end = cached_row
             setattr(obj, f.get_cache_name(), rel_obj)
+
+            # Do the reverse cache if the field is a unique relation.
+            if f.unique and f.related_query_name() in dir(f.rel.to):
+                cache_var_name = rel_obj.__class__.__dict__[f.related_query_name()].cache_name
+                setattr(rel_obj, cache_var_name, obj)
+            
+    if restricted:
+        related_fields = [(x.field, x.model) for x in klass._meta.get_all_related_objects() if x.field.unique]
+        for f, model in related_fields:
+            if f.related_query_name() not in requested:
+                continue
+
+            next = requested.get(f.related_query_name(), {})
+            cached_row = get_cached_row(model, row, index_end, max_depth,
+                    cur_depth+1, next)
+            if cached_row:
+                rel_obj, index_end = cached_row
+                setattr(rel_obj, f.get_cache_name(), obj)
+                
+                # Now do the reverse cache.
+                cache_var_name = obj.__class__.__dict__[f.related_query_name()].cache_name
+                setattr(obj, cache_var_name, rel_obj)
+    
     return obj, index_end
 
 def delete_objects(seen_objs):
Index: tests/modeltests/select_related_reverse/__init__.py
===================================================================
Index: tests/modeltests/select_related_reverse/models.py
===================================================================
--- tests/modeltests/select_related_reverse/models.py	(revision 0)
+++ tests/modeltests/select_related_reverse/models.py	(revision 0)
@@ -0,0 +1,123 @@
+"""
+``select_related()`` follows all forward relationships, but should also follow
+reverse relationships where it is appropriate (currently for OneToOneFields 
+only).
+"""
+
+from django.db import models
+
+# OneToOneField tests only.
+
+class User(models.Model):
+    alias = models.CharField(max_length=20)
+    
+    def __unicode__(self):
+        return 'User, alias = %s' % (self.alias,)
+
+
+class UserInfo(models.Model):
+    user = models.OneToOneField(User, primary_key=True)
+    name = models.CharField(max_length=32)
+
+    def __unicode__(self):
+        return 'UserInfo, name = %s' % (self.name,)
+    
+
+class UserStatResults(models.Model):
+    results = models.CharField(max_length=50)
+
+    def __unicode__(self):
+        return 'UserStatResults, results = %s' % (self.results,)
+    
+
+class UserStat(models.Model):
+    user = models.OneToOneField(User, primary_key=True)
+    posts = models.IntegerField()
+    results = models.ForeignKey(UserStatResults)
+
+    def __unicode__(self):
+        return 'UserStat, posts = %s' % (self.posts,)
+
+
+class StatDetails(models.Model):
+    base_stats = models.OneToOneField(UserStat, primary_key=True)
+    comments = models.IntegerField()
+
+    def __unicode__(self):
+        return 'StatDetails, comments = %s' % (self.comments,)
+
+
+__test__ = {'API_TESTS':"""
+
+# Set up.
+# The test runner sets settings.DEBUG to False, but we want to gather queries
+# so we'll set it to True here and reset it at the end of the test suite.
+>>> from django.conf import settings
+>>> settings.DEBUG = True
+>>> from django import db
+
+>>> usr = UserStatResults.objects.create(results='first results')
+>>> u = User.objects.create(alias='tom')
+>>> ui = UserInfo.objects.create(user=u, name='Tom Jones')
+>>> stat = UserStat.objects.create(user=u, posts=150, results=usr)
+>>> sd = StatDetails.objects.create(base_stats=stat, comments=259)
+>>> u = User.objects.create(alias='john')
+>>> ui = UserInfo.objects.create(user=u, name='John Smith')
+>>> stat = UserStat.objects.create(user=u, posts=33, results=usr)
+>>> sd = StatDetails = StatDetails.objects.create(base_stats=stat, comments=104)
+
+# Specifying models in the select_related(...) works as expected.
+>>> db.reset_queries()
+>>> u = User.objects.select_related('userinfo', 'userstat').get(alias='tom')
+>>> u.userstat
+<UserStat: UserStat, posts = 150>
+>>> len(db.connection.queries)
+1
+>>> u.userstat.statdetails
+<StatDetails: StatDetails, comments = 259>
+>>> len(db.connection.queries)
+2
+>>> u.userinfo
+<UserInfo: UserInfo, name = Tom Jones>
+>>> len(db.connection.queries)
+2
+>>> db.reset_queries()
+>>> u = User.objects.select_related('userstat', 'userstat__statdetails', 'userstat__results').get(alias='tom')
+>>> u.userstat
+<UserStat: UserStat, posts = 150>
+>>> len(db.connection.queries)
+1
+>>> u.userstat.statdetails
+<StatDetails: StatDetails, comments = 259>
+>>> len(db.connection.queries)
+1
+>>> u.userstat.results
+<UserStatResults: UserStatResults, results = first results>
+>>> len(db.connection.queries)
+1
+>>> u.userinfo
+<UserInfo: UserInfo, name = Tom Jones>
+>>> len(db.connection.queries)
+2
+
+>>> db.reset_queries()
+>>> us = UserStat.objects.select_related('user__userinfo').get(user__alias='john')
+>>> us
+<UserStat: UserStat, posts = 33>
+>>> len(db.connection.queries)
+1
+>>> us.user
+<User: User, alias = john>
+>>> len(db.connection.queries)
+1
+>>> us.user.userinfo
+<UserInfo: UserInfo, name = John Smith>
+>>> len(db.connection.queries)
+1
+>>> us.user.userstat
+<UserStat: UserStat, posts = 33>
+>>> len(db.connection.queries)
+1
+
+"""}
+    
\ No newline at end of file
Index: docs/db-api.txt
===================================================================
--- docs/db-api.txt	(revision 7601)
+++ docs/db-api.txt	(working copy)
@@ -889,6 +889,46 @@
 list of fields and the ``depth`` parameter in the same ``select_related()``
 call, since they are conflicting options.
 
+**New in Django development version:** If you are using OneToOneFields, you
+can refer to them from either side of the relationship via their related 
+field names in ``select_related()``, and they will be followed and cached
+appropriately.  Also, any ``ForeignKey`` relations that are appropriate to be
+followed from either side of the OneToOneField relation can be, in the same
+way that is described above.  For example, if we have the following::
+
+class User(models.Model):
+    alias = models.CharField(...)
+    
+class UserInfo(models.Model):
+    user = models.OneToOneField(User)
+    name = models.CharField(...)
+
+class UserStatResults(models.Model):
+    results = models.CharField(...)
+
+class UserStat(models.Model):
+    user = models.OneToOneField(User)
+    posts = models.IntegerField(...)
+    results = models.ForeignKey(UserStatResults)
+
+This is valid::
+
+    User.objects.select_related('userstat__results', 'userinfo')
+    
+This would cache not only the UserStat and UserInfo instances that are 
+appropriate to be cached, but also any UserStatResults instances, 
+since the ForeignKey goes in the proper direction from UserStat.
+
+This is also valid::
+
+    ui = UserInfo.objects.select_related('user__userstat').get(id=1)
+    print ui.user.userstat
+    print ui.user.userinfo.user.userstat
+    
+This would cache all the UserInfo, User and UserStat objects that are selected
+by the criteria, and would generate no extra queries no matter how the related
+OneToOneFields are chained together. 
+
 ``extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)``
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
