Index: django/contrib/gis/db/models/sql/query.py
===================================================================
--- django/contrib/gis/db/models/sql/query.py	(revision 10428)
+++ django/contrib/gis/db/models/sql/query.py	(working copy)
@@ -74,7 +74,7 @@
                     table = self.alias_map[alias][TABLE_NAME]
                     if table in only_load and col not in only_load[table]:
                         continue
-                    r = self.get_field_select(field, alias)
+                    r = self.get_field_select(field, alias, column)
                     if with_aliases:
                         if col[1] in col_aliases:
                             c_alias = 'Col%d' % len(col_aliases)
@@ -112,7 +112,7 @@
 
         # This loop customized for GeoQuery.
         for (table, col), field in izip(self.related_select_cols, self.related_select_fields):
-            r = self.get_field_select(field, table)
+            r = self.get_field_select(field, table, col)
             if with_aliases and col in col_aliases:
                 c_alias = 'Col%d' % len(col_aliases)
                 result.append('%s AS %s' % (r, c_alias))
@@ -213,7 +213,7 @@
         values = [self.convert_values(v, self.extra_select_fields.get(a, None))
                   for v, a in izip(row[rn_offset:index_start], aliases)]
         if SpatialBackend.oracle or getattr(self, 'geo_values', False):
-            # We resolve the columns 
+            # We resolve the columns
             for value, field in izip(row[index_start:], fields):
                 values.append(self.convert_values(value, field))
         else:
@@ -260,19 +260,20 @@
             sel_fmt = sel_fmt % self.custom_select[alias]
         return sel_fmt
 
-    def get_field_select(self, fld, alias=None):
+    def get_field_select(self, field, alias=None, column=None):
         """
         Returns the SELECT SQL string for the given field.  Figures out
         if any custom selection SQL is needed for the column  The `alias`
         keyword may be used to manually specify the database table where
         the column exists, if not in the model associated with this
-        `GeoQuery`.
+        `GeoQuery`.  Similarly, `column` may be used to specify the exact
+        column name, rather than using the `column` attribute on `field`.
         """
-        sel_fmt = self.get_select_format(fld)
-        if fld in self.custom_select:
-            field_sel = sel_fmt % self.custom_select[fld]
+        sel_fmt = self.get_select_format(field)
+        if field in self.custom_select:
+            field_sel = sel_fmt % self.custom_select[field]
         else:
-            field_sel = sel_fmt % self._field_column(fld, alias)
+            field_sel = sel_fmt % self._field_column(field, alias, column)
         return field_sel
 
     def get_select_format(self, fld):
@@ -302,17 +303,18 @@
         return sel_fmt
 
     # Private API utilities, subject to change.
-    def _field_column(self, field, table_alias=None):
+    def _field_column(self, field, table_alias=None, column=None):
         """
         Helper function that returns the database column for the given field.
         The table and column are returned (quoted) in the proper format, e.g.,
         `"geoapp_city"."point"`.  If `table_alias` is not specified, the
         database table associated with the model of this `GeoQuery` will be
-        used.
+        used.  If `column` is specified, it will be used instead of the value
+        in `field.column`.
         """
         if table_alias is None: table_alias = self.model._meta.db_table
         return "%s.%s" % (self.quote_name_unless_alias(table_alias),
-                          self.connection.ops.quote_name(field.column))
+                          self.connection.ops.quote_name(column or field.column))
 
     def _geo_field(self, field_name=None):
         """
Index: django/contrib/gis/tests/relatedapp/tests.py
===================================================================
--- django/contrib/gis/tests/relatedapp/tests.py	(revision 10428)
+++ django/contrib/gis/tests/relatedapp/tests.py	(working copy)
@@ -183,7 +183,6 @@
             self.assertEqual(m.point, d['point'])
             self.assertEqual(m.point, t[1])
 
-    # Test disabled until #10572 is resolved.
     def test08_defer_only(self):
         "Testing defer() and only() on Geographic models."
         qs = Location.objects.all()
@@ -191,6 +190,26 @@
         for loc, def_loc in zip(qs, def_qs):
             self.assertEqual(loc.point, def_loc.point)
 
+    def test09_pk_relations(self):
+        "Ensuring correct primary key column is selected across relations. See #10757."
+        # Adding two more cities, but this time making sure that their location
+        # ID values do not match their City ID values.
+        loc1 = Location.objects.create(point='POINT (-95.363151 29.763374)')
+        loc2 = Location.objects.create(point='POINT (-96.801611 32.782057)')
+        dallas = City.objects.create(name='Dallas', location=loc2)
+        houston = City.objects.create(name='Houston', location=loc1)
+
+        # The expected ID values -- notice the last two location IDs
+        # are out of order.  We want to make sure that the related
+        # location ID column is selected instead of ID column for
+        # the city.
+        city_ids = (1, 2, 3, 4, 5)
+        loc_ids = (1, 2, 3, 5, 4)
+        ids_qs = City.objects.order_by('id').values('id', 'location__id')
+        for val_dict, c_id, l_id in zip(ids_qs, city_ids, loc_ids):
+            self.assertEqual(val_dict['id'], c_id)
+            self.assertEqual(val_dict['location__id'], l_id)
+
     # TODO: Related tests for KML, GML, and distance lookups.
 
 def suite():
