Index: django/db/models/fields/related.py
===================================================================
--- django/db/models/fields/related.py	(revision 16622)
+++ django/db/models/fields/related.py	(working copy)
@@ -171,44 +171,30 @@
         raise TypeError("Related Field has invalid lookup: %s" % lookup_type)
 
     def _pk_trace(self, value, prep_func, lookup_type, **kwargs):
-        # Value may be a primary key, or an object held in a relation.
-        # If it is an object, then we need to get the primary key value for
-        # that object. In certain conditions (especially one-to-one relations),
-        # the primary key may itself be an object - so we need to keep drilling
-        # down until we hit a value that can be used for a comparison.
-        v = value
-
-        # In the case of an FK to 'self', this check allows to_field to be used
-        # for both forwards and reverse lookups across the FK. (For normal FKs,
-        # it's only relevant for forward lookups).
-        if isinstance(v, self.rel.to):
-            field_name = getattr(self.rel, "field_name", None)
+        rel_meta = self.rel.to._meta
+        if isinstance(value, self.rel.to):
+            rel_meta = self.rel.to._meta
+            field_name = getattr(self.rel, "field_name", rel_meta.pk.name)
+            field = rel_meta.get_field(field_name)
+            value = getattr(value, field.attname)
+        elif hasattr(value, '_meta'):
+            # This is a probably a reverse lookup.
+            field = value._meta.pk
+            value = value.pk
         else:
-            field_name = None
-        try:
-            while True:
-                if field_name is None:
-                    field_name = v._meta.pk.name
-                v = getattr(v, field_name)
-                field_name = None
-        except AttributeError:
-            pass
-        except exceptions.ObjectDoesNotExist:
-            v = None
-
-        field = self
-        while field.rel:
-            if hasattr(field.rel, 'field_name'):
-                field = field.rel.to._meta.get_field(field.rel.field_name)
-            else:
-                field = field.rel.to._meta.pk
-
+            field = self
+            while field.rel:
+                if hasattr(field.rel, 'field_name'):
+                    field = field.rel.to._meta.get_field(field.rel.field_name)
+                else:
+                    field = field.rel.to._meta.pk
+            
         if lookup_type in ('range', 'in'):
-            v = [v]
-        v = getattr(field, prep_func)(lookup_type, v, **kwargs)
-        if isinstance(v, list):
-            v = v[0]
-        return v
+            value = [value]
+        value = getattr(field, prep_func)(lookup_type, value, **kwargs)
+        if isinstance(value, list):
+            value = value[0]
+        return value
 
     def related_query_name(self):
         # This method defines the name that can be used to identify this
@@ -461,9 +447,9 @@
                 clear.alters_data = True
 
         manager = RelatedManager()
-        attname = rel_field.rel.get_related_field().name
-        manager.core_filters = {'%s__%s' % (rel_field.name, attname):
-                getattr(instance, attname)}
+        to_field = rel_field.rel.get_related_field()
+        manager.core_filters = {'%s__%s' % (rel_field.name, to_field.name):
+                getattr(instance, to_field.attname)}
         manager.model = self.related.model
 
         return manager
Index: tests/modeltests/model_inheritance/tests.py
===================================================================
--- tests/modeltests/model_inheritance/tests.py	(revision 16622)
+++ tests/modeltests/model_inheritance/tests.py	(working copy)
@@ -4,7 +4,7 @@
 from django.test import TestCase
 
 from models import (Chef, CommonInfo, ItalianRestaurant, ParkingLot, Place,
-    Post, Restaurant, Student, StudentWorker, Supplier, Worker, MixinModel)
+    Post, Restaurant, Person, Student, StudentWorker, Supplier, Worker, MixinModel)
 
 
 class ModelInheritanceTests(TestCase):
@@ -270,6 +270,26 @@
             lambda: ItalianRestaurant.objects.select_related("chef")[0].chef
         )
 
+    def test_pktrace(self):
+        r = Restaurant.objects.create(
+            name="Demon Dogs",
+            address="944 W. Fullerton",
+            serves_hot_dogs=True,
+            serves_pizza=False,
+            rating=2
+        )
+        p = Person.objects.create(
+            name="John", 
+            favorite_restaurant=r
+        )
+
+        self.assertNumQueries(1, 
+            lambda: list(Person.objects.filter(favorite_restaurant=r))
+        )
+        self.assertNumQueries(1, 
+            lambda: list(r.fans.all())
+        )
+
     def test_mixin_init(self):
         m = MixinModel()
         self.assertEqual(m.other_attr, 1)
Index: tests/modeltests/model_inheritance/models.py
===================================================================
--- tests/modeltests/model_inheritance/models.py	(revision 16622)
+++ tests/modeltests/model_inheritance/models.py	(working copy)
@@ -119,6 +119,11 @@
     def __unicode__(self):
         return u"%s the parking lot" % self.name
 
+
+class Person(models.Model):
+    name = models.CharField(max_length=50)
+    favorite_restaurant = models.ForeignKey(Restaurant, related_name="fans")
+
 #
 # Abstract base classes with related models where the sub-class has the
 # same name in a different app and inherits from the same abstract base
